Проверяет понимание различий и взаимосвязи принципов SOLID — Interface Segregation и Single Responsibility — на примере проектирования интерфейсов.
Оба принципа входят в SOLID, но работают на разных уровнях абстракции. SRP (Single Responsibility Principle) формулируется так: у класса должна быть только одна причина для изменения. Это значит, что класс должен отвечать за одну функциональную область. ISP (Interface Segregation Principle) утверждает: клиент не должен зависеть от методов, которые он не использует. То есть интерфейсы следует делать узкими и специализированными под конкретных потребителей.
На практике ISP часто становится инструментом достижения SRP. Если у класса «толстый» интерфейс с десятком методов, реализация вынуждена отвечать за всё сразу — это нарушает SRP. Разбив интерфейс на несколько узких, мы получаем классы с одной ответственностью.
// Нарушение ISP и SRP
interface Worker {
work(): void;
eat(): void;
sleep(): void;
}
class Robot implements Worker {
work() { /* ok */ }
eat() { throw new Error('Robot cannot eat'); }
sleep() { throw new Error('Robot cannot sleep'); }
}
// Решение: разделяем интерфейсы
interface Workable { work(): void; }
interface Feedable { eat(): void; }
class Robot implements Workable {
work() { /* ok */ }
}
class Human implements Workable, Feedable {
work() { /* ok */ }
eat() { /* ok */ }
}В TypeScript и Java это особенно заметно: большие интерфейсы заставляют классы реализовывать ненужные методы или бросать исключения. Разделение на мелкие интерфейсы упрощает тестирование, мокирование и замену реализаций. В React, например, пропсы компонента — это тоже своего рода интерфейс: если компонент принимает 20 пропсов, часть из которых не использует, это сигнал о нарушении ISP и SRP.
Итог: SRP и ISP дополняют друг друга. SRP задаёт цель — одна ответственность, ISP даёт приём — узкие интерфейсы. Применяйте их вместе при проектировании модулей и контрактов, чтобы код был гибким и легко тестируемым.