Зачем инвертировать зависимости?
Продвинутые темы
Инвертировать зависимости (Dependency Inversion) нужно, чтобы модули зависели от абстракций, а не от конкретных реализаций — это снижает связанность и упрощает замену и тестирование.
Проблема прямой зависимости
Модуль верхнего уровня жёстко зависит от конкретной реализации — трудно заменить и тестировать:
class UserService {
constructor() {
this.db = new PostgresDB(); // жёсткая привязка к реализации
}
}Инверсия зависимостей
Зависимость передаётся извне через абстракцию (интерфейс):
class UserService {
constructor(db) { // зависит от абстракции "хранилище"
this.db = db;
}
}
new UserService(new PostgresDB()); // прод
new UserService(new MockDB()); // тестТеперь UserService не знает конкретную БД — только контракт.
Зачем это нужно
- Тестируемость — легко подставить мок.
- Гибкость — заменить реализацию (Postgres → Mongo) без изменения потребителя.
- Слабая связанность — модули не завязаны на детали.
- Расширяемость — новые реализации без правки существующего кода.
Связь с SOLID
Это буква D в SOLID (Dependency Inversion Principle): «зависеть от абстракций, а не от конкретики». Реализуется через Dependency Injection.
Коротко для собеседования
Инверсия зависимостей заставляет модули зависеть от абстракций, а не от конкретных реализаций (передавать зависимость извне). Даёт тестируемость (моки), гибкость (замена реализации) и слабую связанность. Это принцип D в SOLID, реализуемый через Dependency Injection.