Ответ
Принцип разделения интерфейсов (ISP) утверждает, что клиенты не должны зависеть от методов, которые они не используют. В Dart это реализуется через создание небольших, специфичных интерфейсов (абстрактных классов), а не одного громоздкого.
Пример нарушения ISP:
// Один интерфейс для всех сущностей, заставляющий реализовывать ненужные методы.
abstract class Worker {
void code();
void test();
void deploy();
void cook();
}
class Developer implements Worker {
@override
void code() => print('Writing Flutter app');
@override
void test() => print('Running unit tests');
@override
void deploy() => print('Deploying to Firebase');
@override
void cook() => throw UnimplementedError('Developer cannot cook!'); // Ненужный метод!
}
Пример следования ISP:
// Разделяем на логичные, узкие интерфейсы.
abstract class Codeable {
void code();
}
abstract class Testable {
void test();
}
abstract class Deployable {
void deploy();
}
abstract class Cookable {
void cook();
}
// Классы реализуют только нужные им интерфейсы.
class FlutterDeveloper implements Codeable, Testable, Deployable {
@override
void code() => print('Writing Flutter app with Dart');
@override
void test() => print('Running widget tests');
@override
void deploy() => print('Building APK/IPA and deploying to store');
}
class Chef implements Cookable {
@override
void cook() => print('Cooking dinner');
}
Преимущества:
- Избегаем «жирных» интерфейсов. Классы не загрязнены нерелевантными методами.
- Повышаем стабильность. Изменения в одном интерфейсе (например,
Deployable) затрагивают только классы, которые от него зависят, а не всех «работников». - Упрощаем тестирование и понимание. Легче мокать и тестировать небольшие контракты.