В чём заключается принцип разделения интерфейсов (ISP) и как его реализовать?

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

Ответ

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

Проблема — нарушение ISP:

protocol Worker {
    func work()
    func eat()
    func code() // Не нужен повару!
}

class Chef: Worker {
    func work() { /* готовит */ }
    func eat() { /* ест */ }
    func code() { // Пустая или заглушка! Нарушение принципа.
        fatalError("Повар не программирует")
    }
}

Решение — разделение интерфейсов:

// Мелкие, специфичные протоколы
protocol Workable {
    func work()
}

protocol Eatable {
    func eat()
}

protocol Codeable {
    func code()
}

// Классы реализуют только то, что им нужно
class Chef: Workable, Eatable {
    func work() { print("Готовит ужин") }
    func eat() { print("Пробует блюдо") }
}

class Programmer: Workable, Eatable, Codeable {
    func work() { print("Пишет ТЗ") }
    func eat() { print("Пьёт кофе") }
    func code() { print("Пишет код на Swift") }
}

Итог: Вместо одного монолитного Worker мы создали три узкоспециализированных протокола. Chef не зависит от метода code(). Это повышает гибкость, уменьшает связность и упрощает тестирование.