Ответ
Принцип разделения интерфейсов (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(). Это повышает гибкость, уменьшает связность и упрощает тестирование.
Ответ 18+ 🔞
Э, слушай, смотри, есть такая хуйня — принцип разделения интерфейсов. По-умному ISP. А суть-то проще пареной репы, блядь: клиенты не должны зависеть от методов, которые они нихуя не используют. Представь, тебе дали пульт от всего на свете: телевизор включить, машину завести, чайник вскипятить и ещё хуй знает что. А ты просто чай попить хочешь. И ты, такой, стоишь с этой ебучей панелью, кнопок дохуя, а нужна одна. Вот это и есть нарушение, пиздец.
В чём проблема-то, на примере?
Смотри, нарисовали мы протокол Worker — «Работник». И там всё в кучу: и работать, и жрать, и код писать. А теперь представь повара. Ну, сука, Герасим из кухни. Ему код писать нахуй не сдался!
protocol Worker {
func work()
func eat()
func code() // А это повару зачем, блядь? Он не программист, он пельмени лепит!
}
class Chef: Worker {
func work() { /* готовит, парит, жарит */ }
func eat() { /* ну, пробует, жрёт, чё */ }
func code() { // И что тут делать, ёпта?!
fatalError("Повар не программирует, иди нахуй")
// Либо пустышку оставить — тоже пиздец, архитектурный кал.
}
}
Вот видишь? Заставили бедолагу метод code() реализовывать. А он нихуя в этом не шарит! Это как Герасима заставить на флейте играть. «А че ты на мне то, сука, играешь, падла ты поганая?!». Вот именно.
А как правильно-то? Да всё просто, блядь. Не надо делать один жирный протокол на все случаи жизни. Дроби эту хуйню! Сделай несколько мелких, узкоспециализированных.
// Разделили, как хорошие ребята
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, матерится на Optionals") }
}
И что в итоге, блядь?
А в итоге — красота! Вместо одного монструозного Worker, от которого все зависят и тащат за собой кучу ненужного хлама, у нас аккуратные, маленькие протоколы. Повар спокоен, ему не впендюрили лишнюю ответственность. Код чистый, гибкий, тестируется легче. Связность — низкая, как моё терпение, когда вижу нарушение ISP.
Запомни, чувак: не заставляй классы реализовывать то, что им нахуй не нужно. Это как дать Тургеневу писать инструкцию к микроволновке. Он скажет: «Мууу...», и пойдёт Муму топить. А нам такое надо? Нет, блядь.