Ответ
Принцип инверсии зависимостей (Dependency Inversion Principle, DIP) — это один из пяти принципов SOLID, направленный на уменьшение связанности (coupling) между программными модулями.
Он гласит, что:
- Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те, и другие должны зависеть от абстракций (например, интерфейсов).
- Абстракции не должны зависеть от деталей. Детали (конкретные реализации) должны зависеть от абстракций.
Проще говоря, высокоуровневая логика не должна зависеть от низкоуровневых деталей реализации. Это позволяет легко заменять компоненты системы без изменения основной логики.
Пример на Python
Проблема: Прямая зависимость
Класс Switch напрямую зависит от конкретного класса LightBulb. Если мы захотим управлять вентилятором, придется изменять Switch.
class LightBulb:
def turn_on(self):
print("Лампочка включена")
class Switch:
# Switch жестко связан с LightBulb
def __init__(self, bulb: LightBulb):
self.bulb = bulb
def operate(self):
self.bulb.turn_on()
Решение: Зависимость от абстракции
Вводим абстракцию Switchable. Теперь Switch зависит от нее, а не от конкретной реализации.
from abc import ABC, abstractmethod
# 1. Создаем абстракцию
class Switchable(ABC):
@abstractmethod
def turn_on(self):
pass
# 2. Детали зависят от абстракции
class LightBulb(Switchable):
def turn_on(self):
print("Лампочка включена")
class Fan(Switchable):
def turn_on(self):
print("Вентилятор включен")
# 3. Модуль верхнего уровня зависит от абстракции
class Switch:
def __init__(self, device: Switchable):
self.device = device
def operate(self):
self.device.turn_on()
# Теперь Switch может управлять любым устройством, реализующим Switchable
lamp_switch = Switch(LightBulb())
fan_switch = Switch(Fan())
lamp_switch.operate() # Вывод: Лампочка включена
fan_switch.operate() # Вывод: Вентилятор включен
Таким образом, DIP делает систему более гибкой, тестируемой и расширяемой.