Что такое принцип разделения интерфейсов (ISP)?

«Что такое принцип разделения интерфейсов (ISP)?» — вопрос из категории Паттерны, который задают на 28% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Interface Segregation Principle (ISP) — это один из пяти принципов SOLID, который гласит, что клиенты не должны зависеть от интерфейсов, которые они не используют. Вместо одного «толстого» интерфейса лучше создавать несколько узкоспециализированных.

Проблема: Класс, реализующий большой интерфейс, вынужден предоставлять реализации всех методов, даже если они ему не нужны. Это приводит к раздуванию кода, нарушению инкапсуляции и хрупким зависимостям.

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

// «Толстый» интерфейс, нарушающий ISP
interface Worker {
    void work();
    void eat();
}

class Human implements Worker {
    public void work() { /* Человек работает */ }
    public void eat() { /* Человек ест */ }
}

class Robot implements Worker {
    public void work() { /* Робот работает */ }
    // Роботу не нужно есть, но метод реализовать обязан
    public void eat() { 
        throw new UnsupportedOperationException("Robots don't eat!");
    }
}

Решение согласно ISP:

// Разделяем интерфейсы по ответственности
interface Workable {
    void work();
}

interface Eatable {
    void eat();
}

// Классы реализуют только нужные им интерфейсы
class Human implements Workable, Eatable {
    public void work() { /* ... */ }
    public void eat() { /* ... */ }
}

class Robot implements Workable {
    public void work() { /* ... */ }
    // Метод eat() не требуется
}

Практические преимущества ISP:

  • Снижение связности: Классы зависят только от необходимого функционала.
  • Упрощение поддержки: Изменения в одном интерфейсе затрагивают меньшее количество классов.
  • Улучшение тестируемости: Легче создавать моки и стабы для узких интерфейсов.
  • Предотвращение «взрывов зависимостей»: Избегается ситуация, когда изменение в неиспользуемом методе главного интерфейса требует правок во всех его реализациях.