Какие проблемы возникают при жёсткой связи (tight coupling) объектов в композиции?

«Какие проблемы возникают при жёсткой связи (tight coupling) объектов в композиции?» — вопрос из категории ООП, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основная проблема — жёсткая связь (tight coupling) между объектами. Когда класс-контейнер сам создаёт экземпляры своих зависимостей, это приводит к:

  • Сложности тестирования: Невозможно легко подменить зависимый объект на мок-объект (mock) для изоляции тестируемого компонента.
  • Низкой гибкости и переиспользуемости: Замена одной реализации компонента на другую требует изменения кода класса-контейнера.

❌ Неправильный подход: Жёсткая связь

class Engine:
    def start(self):
        print("Engine started")

class Car:
    def __init__(self):
        # Жёсткое создание зависимости внутри класса
        self.engine = Engine()

    def start(self):
        self.engine.start()

# Мы не можем создать Car с другим типом двигателя без изменения класса Car
my_car = Car()

✅ Правильный подход: Внедрение зависимостей (Dependency Injection)

Правильным подходом является Внедрение зависимостей (Dependency Injection, DI), когда зависимости передаются в объект извне (например, через конструктор).

class ElectricEngine:
    def start(self):
        print("Electric engine started silently")

class Car:
    def __init__(self, engine):
        # Зависимость передаётся извне
        self.engine = engine

    def start(self):
        self.engine.start()

# Теперь мы можем гибко конфигурировать Car
electric_engine = ElectricEngine()
my_electric_car = Car(engine=electric_engine)
my_electric_car.start()

Этот подход инвертирует управление (Inversion of Control), делая код модульным, слабо связанным и легко тестируемым.