Ответ
Нарушение принципа инверсии зависимостей (Dependency Inversion Principle - DIP) приводит к созданию жестко связанного (tightly coupled) кода, где высокоуровневые модули напрямую зависят от низкоуровневых реализаций.
Это порождает следующие проблемы:
- Сложность тестирования: Невозможно легко подменить реальные зависимости (например, базу данных) на тестовые заглушки (mocks), что усложняет написание изолированных юнит-тестов.
- Низкая гибкость и сложность поддержки: Изменение в низкоуровневом модуле (например, смена
MySQLDatabaseнаPostgreSQLDatabase) требует изменений во всех высокоуровневых модулях, которые его используют. - Затрудненное переиспользование: Модули нельзя легко переиспользовать в других контекстах, так как они "тащат" за собой свои конкретные зависимости.
👎 Неправильный подход (жесткая связь)
Высокоуровневый модуль UserService напрямую зависит от конкретной реализации MySQLDatabase.
class MySQLDatabase:
def save_user(self, user_data):
print(f"Saving {user_data} to MySQL")
class UserService: # Высокоуровневый модуль
def __init__(self):
# Прямая зависимость от конкретного класса
self.db = MySQLDatabase()
def register_user(self, data):
self.db.save_user(data)
👍 Правильный подход (с инверсией зависимости)
Вводится абстракция (DatabaseInterface), от которой зависят оба модуля.
from abc import ABC, abstractmethod
# 1. Создаем абстракцию (интерфейс)
class DatabaseInterface(ABC):
@abstractmethod
def save_user(self, user_data): pass
# 2. Низкоуровневый модуль реализует интерфейс
class MySQLDatabase(DatabaseInterface):
def save_user(self, user_data):
print(f"Saving {user_data} to MySQL")
# 3. Высокоуровневый модуль зависит от абстракции
class UserService:
def __init__(self, db: DatabaseInterface):
# Зависимость внедряется через конструктор и опирается на абстракцию
self.db = db
def register_user(self, data):
self.db.save_user(data)
Теперь класс UserService можно легко протестировать, передав ему mock-объект, или переключить на PostgreSQLDatabase, если та реализует тот же интерфейс, без изменения кода UserService.