Ответ
Принцип инверсии зависимостей (DIP) — последний принцип SOLID. Он решает проблему жесткой связанности между модулями высокого и низкого уровня, что затрудняет тестирование, замену и повторное использование компонентов.
Формулировка:
- Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций.
- Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Проблема (нарушение DIP):
// Класс высокого уровня напрямую зависит от конкретного класса низкого уровня.
class ReportService {
private MySQLDatabase database; // Конкретная зависимость
public void saveReport(Report r) {
database.save(r);
}
}
Решение (следование DIP):
// 1. Абстракция (интерфейс)
interface Database {
void save(Report r);
}
// 2. Деталь (конкретная реализация)
class MySQLDatabase implements Database { /*...*/ }
class PostgreSQLDatabase implements Database { /*...*/ }
// 3. Модуль высокого уровня зависит от абстракции
class ReportService {
private Database database; // Зависимость от абстракции
public ReportService(Database db) { // Внедрение через конструктор
this.database = db;
}
public void saveReport(Report r) {
database.save(r);
}
}
Практическая польза:
- Тестируемость: Легко подменить
Databasemock-объектом в юнит-тестах дляReportService. - Гибкость: Замена СУБД требует лишь создания новой реализации интерфейса, без изменения
ReportService. - Чистая архитектура: Определяет четкое направление зависимости — от бизнес-логики к инфраструктурным деталям.