Dependency Inversion Principle и Dependency Injection (бухгалтер на работе)
Это не соперники и не соседи по цепочке. Это «зачем» и «как»: Dependency Inversion Principle — правило (как части системы должны зависеть друг от друга), а Dependency Injection — самый популярный способ это правило выполнить на практике.
На пальцах
Представь бухгалтера, которая приходит в офис делать отчётность. Её должностная инструкция написана так: «нужен компьютер и табличный редактор» — без названий моделей и версий. Утром в офисе ей выдают конкретный ноутбук, на нём уже стоит конкретный редактор. Завтра — другой ноутбук с другим редактором, а бухгалтер всё так же справляется, потому что инструкцию это не волнует. Dependency Inversion Principle — это как раз про должностную инструкцию: верхняя часть не должна быть привязана к нижней, обе зависят от абстракции («компьютер с редактором, умеющий то-то и то-то»). Dependency Injection — это про утреннюю выдачу: нужная вещь не создаётся внутри, а приходит снаружи.
Что делает каждый
Dependency Inversion Principle (DIP) — буква «D» в наборе SOLID (пять базовых правил проектирования кода). Правило из двух частей: верхняя часть системы не должна быть жёстко привязана к нижней — обе должны зависеть от абстракций, то есть от общего описания «что нужно уметь», а не от того, как это устроено внутри. И сами эти абстракции не должны зависеть от деталей реализации — детали подстраиваются под абстракцию. Это уровень архитектуры: как слои системы должны быть связаны между собой.
Dependency Injection (DI) — приём в коде. Вместо того чтобы объект сам создавал то, что ему нужно для работы, ему это передают снаружи: через конструктор (метод, который вызывается при создании объекта), через отдельный метод-сеттер или прямо в поле (переменную) объекта. Это уровень реализации: конкретные строчки в конкретном классе.
В чём разница
| Dependency Inversion Principle | Dependency Injection | |
|---|---|---|
| Что это | Принцип проектирования (одно из правил SOLID) | Приём написания кода |
| Где живёт | В голове архитектора, в диаграммах, в правилах команды | В конкретных строках кода класса |
| Про что | Как части системы должны зависеть друг от друга | Как именно передать нужную вещь объекту |
| Кто применяет | Архитектор или тимлид при проектировании | Программист при написании класса |
| Что даёт | Независимость слоёв, заменяемость реализаций | Возможность подменять зависимости (включая тестовые заглушки) |
| Без чего не работает | Без этого принципа замена реализаций становится кошмаром | Без DI принцип сложно соблюсти, но можно и другими способами |
Что из этого следует
Dependency Inversion Principle нужен почти всегда — это одно из фундаментальных правил SOLID, без которого большая система превращается в спагетти: любое изменение тянет за собой полпроекта. Dependency Injection — главный, но не единственный способ этот принцип выполнить: есть, например, «локатор сервисов», когда объект сам ходит за зависимостью в одно общее место. На практике Dependency Inversion Principle живёт в архитектуре и договорённостях команды, Dependency Injection — в коде. Когда в команде говорят «у нас Dependency Inversion Principle» — имеют в виду «слои не связаны жёстко». Когда говорят «у нас Dependency Injection» — имеют в виду «зависимости передаются через конструктор».