Что означает принцип инверсии зависимостей (D) в SOLID?

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

Ответ

D в SOLID означает Dependency Inversion Principle (DIP) — Принцип инверсии зависимостей.

Формулировка:

  1. Модули верхнего уровня (политика, бизнес-логика) не должны зависеть от модулей нижнего уровня (утилиты, детали реализации). Оба должны зависеть от абстракций (интерфейсов или абстрактных классов).
  2. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

Цель: Снизить связанность между модулями, повысить гибкость и тестируемость системы.

Пример нарушения DIP:

class ReportService {
    private PdfReportGenerator pdfGenerator; // Прямая зависимость от детали
    public void generate() {
        pdfGenerator.generate();
    }
}

Пример соблюдения DIP:

// Абстракция
interface ReportGenerator {
    void generate();
}

// Деталь 1
class PdfReportGenerator implements ReportGenerator {
    @Override
    public void generate() { /* Генерация PDF */ }
}

// Деталь 2
class HtmlReportGenerator implements ReportGenerator {
    @Override
    public void generate() { /* Генерация HTML */ }
}

// Модуль верхнего уровня зависит от абстракции
class ReportService {
    private final ReportGenerator generator; // Зависимость от интерфейса

    public ReportService(ReportGenerator generator) { // Внедрение через конструктор
        this.generator = generator;
    }

    public void generate() {
        generator.generate();
    }
}

Почему это важно: ReportService теперь не знает о конкретных реализациях. Мы можем легко заменить PdfReportGenerator на HtmlReportGenerator или добавить новую реализацию, не изменяя код ReportService. Это основа для Dependency Injection.