Что такое принцип разделения интерфейса (Interface Segregation Principle)
Что проверяют
Понимаете ли вы, что ISP про клиента, а не про размер интерфейса. Формулировка гласит: клиент не должен зависеть от методов, которыми не пользуется. Значит резать нужно по потребителям, а не по красоте имён. В Java у вопроса прямые последствия: лишний метод в интерфейсе заставляет все реализации писать заглушки, а всех вызывающих пересобираться.
Как отвечать
Начните с проблемы. Есть один широкий интерфейс, его реализуют разные классы, и части методов у каждого нет:
interface Report {
byte[] render();
void schedule(Cron cron);
void email(String to);
}Класс, который умеет только отрисовать, вынужден бросать UnsupportedOperationException в двух методах из трёх.
Решение: разделить по ролям клиентов на Renderable, Schedulable и Sendable, а класс реализует те роли, которые действительно поддерживает. Вызывающий объявляет параметр самым узким типом, который ему нужен.
Стоит добавить, что методы по умолчанию в интерфейсах соблазняют дать пустую заглушку вместо разделения. Это тот же нереализованный метод, только теперь его не видит компилятор, и нарушение уезжает в рантайм.
Где спотыкаются
Доводят идею до интерфейса с одним методом на каждый чих. Десяток однометодных интерфейсов вместо двух осмысленных ролей усложняет чтение и не убирает ни одной лишней зависимости.
Путают ISP с принципом единой ответственности. SRP про причины изменения модуля, ISP про то, что видит конкретный потребитель; один класс вполне может реализовать несколько узких интерфейсов и остаться в рамках обоих принципов.
Режут интерфейс по реализациям, а не по клиентам. Получается набор интерфейсов, повторяющих классы один в один, а вызывающий код по-прежнему зависит сразу от всего.