Проверяет понимание принципа инверсии зависимостей (DIP) и его отличия от Dependency Injection, что важно для проектирования гибкой архитектуры.
Dependency Inversion Principle (DIP) — это пятый принцип SOLID, сформулированный Робертом Мартином. Он утверждает две вещи: модули верхнего уровня не должны зависеть от модулей нижнего уровня, и оба должны зависеть от абстракций; абстракции не должны зависеть от деталей, а детали должны зависеть от абстракций. Проще говоря, бизнес-логика не должна знать о конкретных реализациях баз данных, HTTP-клиентов или файловых систем.
Без DIP высокоуровневый код жёстко привязан к низкоуровневым деталям. Это усложняет тестирование, замену технологий и повторное использование кода. DIP переворачивает направление зависимостей: вместо того чтобы бизнес-логика импортировала конкретный класс базы данных, она работает с интерфейсом, а конкретная реализация подставляется снаружи.
// Абстракция
interface UserRepository {
findById(id: string): Promise<User>;
}
// Низкоуровневая деталь
class PostgresUserRepository implements UserRepository {
async findById(id: string) { /* SQL-запрос */ }
}
// Высокоуровневый модуль зависит от абстракции
class UserService {
constructor(private repo: UserRepository) {}
async getUser(id: string) {
return this.repo.findById(id);
}
}
// Внедрение зависимости
const service = new UserService(new PostgresUserRepository());
Здесь UserService не знает о Postgres. Мы можем подставить мок в тестах или заменить хранилище на MongoDB, не меняя бизнес-логику.
Итог: DIP стоит применять, когда вы хотите, чтобы бизнес-логика не зависела от конкретных технологий и легко тестировалась. Dependency Injection — удобный инструмент для достижения этой цели, но сам по себе он не гарантирует соблюдение принципа.