
SOLID. Что значит I
I в аббревиатуре SOLID расшифровывается как Interface Segregation Principle, он же Принцип Разделения Интерфейсов. На мой взгляд, это самый простой из принципов SOLID, и сегодня мы о нем поговорим. Как обычно, разберем ISP на примере и посмотрим, что случится, если этим принципом пренебречь.
I – Interface Segregation Principle, он же ISP
Роберт Мартин в свое время провозгласил: «Программные сущности не должны зависеть от методов, которые они не используют».
Все программные сущности тех времен:

Краткое и поверхностное описание принципа разделения интерфейсов можно найти на википедии.
Суть проблемы
Проблема заключалась в том, что в былые времена еще не было большого количества хороших практик, и каждый программист (или команда программистов) писал код так, как умеет. Если результат работал – все были рады.
А затем умные дядьки вроде Мартина, Фаулера, и Макконнелла начали задумываться над тем, как сделать результат не просто рабочим, но и эффективным. И, следовательно, необходимо было научиться писать удобный и легкий в сопровождении код.
Но я немного отвлекся. Проблема «толстых» интерфейсов заключалась в том, что они содержали множество методов на все случаи жизни. А классы, которые эти интерфейсы реализовывали, нуждались лишь в некоторых методах, в то время как в остальных не было никакой нужды.
А теперь представьте ситуацию, когда класс начинает падать лишь потому, что в базовый интерфейс добавился новый метод (реализация которого не определена), либо изменилось имя одного из существующих (и не нужных классу).
И тогда Роберта Мартина осенило: «А что, если делать интерфейсы маленькими?»

ISP на примере
На мой взгляд, принцип разделения интерфейсов очень сильно коррелирует с принципом единой ответственности. Поэтому давайте возьмем пример из поста про SRP и рассмотрим его в контексте ISP.
Итак, представьте, что есть некий интерфейс, который описывает сотрудника компании:
interface Employee {}
Чем может заниматься сотрудник? Это зависит от профиля, но в общем случае сотрудник может заниматься чем угодно: вести бухгалтерию, писать программный код или мыть полы. Если мы добавим эти три метода в наш интерфейс, мы получим фуллстек-разработчика:
interface Employee {
void account(); // вести бухгалтерию
void writeCode(); // писать код
void cleanUp(); // прибраться
}
Допустим, мы хотим создать класс SoftwareEngineer
, который определит реализацию метода writeCode
:
public class SoftwareEngineer implements Employee {
@Override
public void writeCode() {
// Реализация метода
}
}
Вроде бы все нормально – наш класс разработчика реализует интерфейс Employee
и определяет реализацию метода writeCode
. Но ведь интерфейс содержит еще два метода, которым тоже необходимо задать реализацию, верно? И, так как разработчик понятия не имеет, как вести бухгалтерию, а полы мыть не может, потому что у него лапки, то класс SoftwareEngineer в конечном итоге будет выглядеть как-то так:
public class SoftwareEngineer implements Employee {
@Override
public void writeCode() {
// Реализация метода
}
@Override
public void account() {
throw new UnsupportedOperationException("Разработчик не умеет вести бухгалтерию");
}
@Override
public void cleanUp() {
throw new UnsupportedOperationException("У разработчика лапки");
}
}
Возникает вполне логичный вопрос – а можно ли как-то избавиться от двух лишних методов в классе SoftwareEngineer
и оставить только единственно необходимый?
И Роберт Мартин говорит, что да, черт возьми, можно!
ISP в деле
Мы хотим, чтобы наш класс SoftwareEngineer
определял только один метод и не содержал ничего лишнего, как в примере выше:
public class SoftwareEngineer implements Employee {
@Override
public void writeCode() {
// Реализация метода
}
}
Для этого нам нужно определить интерфейс SoftwareEngineer
с единственным методом:
interface SoftwareEngineer {
void writeCode();
}
Теперь мы можем создать три разных класса (джуниор, миддл и сениор разработчики), которые реализуют writeCode
по-разному:
public class JuniorSoftwareEngineer implements SoftwareEngineer {
@Override
public void writeCode() {
// долго думать над задачей
// задавать много вопросов
// написать корявый код с багами
}
}
public class MiddleSoftwareEngineer implements SoftwareEngineer {
@Override
public void writeCode() {
// задать пару вопросов
// понять как и зачем делать задачу
// написать рабочий код
// покрыть код тестами
}
}
public class SeniorSoftwareEngineer implements SoftwareEngineer {
@Override
public void writeCode() {
// подумать, зачем это делать
// сказать, что тут не надо ничего менять, а заказчик дурак
}
}
Аналогично с бухгалтерией и уборкой. Пусть у нас будет базовый интерфейс Cleaner
и две реализации – молодая уборщица и опытная уборщица:
interface Cleaner {
void cleanUp();
}
public class YoungCleaner implements Cleaner {
@Override
public void cleanUp() {
// строить глазки
// смахнуть пыль
}
}
public class ExperiencedCleaner implements Cleaner {
@Override
public void cleanUp() {
// ворчать
// тщательно прибраться
}
}
Что в итоге
С помощью ISP мы получим правильно и логично разделенные интерфейсы. Если мы хотим объявить, что интерфейс нужен для написания кода, то мы добавим в него только метод написания кода. Мы не станем туда добавлять ничего связанного с уборкой помещения. И наоборот – если мы создаем интерфейс для уборки помещения, мы не добавляем в него методы, связанные с кодом или бухгалтерией.
Все это поможет нашим классам быть максимально компактными и эффективно решать поставленные задачи.
Заключение
Когда вы описываете интерфейс, тщательно продумайте, какие операции он должен декларировать. Относятся ли все операции к одной области? Или же интерфейс необходимо разделить?
Конечно, вовсе необязательно делить интерфейсы настолько, чтобы они содержали по одному методу. Например, наш SoftwareEngineer
мог бы иметь еще пару методов: refactor()
, writeUnitTest()
, makeReview()
. Все эти методы описывают работу разработчика. Но если вы захотите добавить в интерфейс SoftwareEngineer
метод cleanOffice()
, то остановитесь и спросите себя, относится ли этот метод к работе разработчика? Стоит ли вынести его в отдельный интерфейс?
Не огорчайте Дядюшку Боба, создавайте проработанные и конкретные интерфейсы!
Предыдущие статьи из цикла SOLID:
S: https://baddev.ru/solid-srp/
O: https://baddev.ru/solid-ocp/
L: https://baddev.ru/solid-lsp/
Понравилось? Подписывайтесь на меня в соцсетях!


cost of ivermectin pill
ivermectin tablets
ivermectin where to buy
ivermectin ingredients
lasix 500 mg price
furosemide uk
furosemide costs
buy lasix 40 mg online
stromectol ireland
ivermectin 3mg dosage
ivermectin buy nz
ivermectin 6
ivermectin protocol
stromectol buy
ivermectin pyrantel pamoate
ivermectin oral
japan ivermectin
buy stromectol pills
lucky land casino
play luckyland slots real money
ivermectin tablets for humans
buy doxycycline online usa
ivermectin 3 mg tablet dosage
stromectol coronavirus
ivermectin 1%cream
ivermectin 8 mg
ivermectin study
ivermectin solubility
cialis walmart prescription
walmart cialis
stromectol tablete cena
buy ivermectin for humans
cost of stromectol
ivermectin for humans over the counter
ivermectin 8000 mcg
stromectol online
generic cialis otc
cialis over counter at walmart
stromectol for lice
generic for ivermectin
how to get cialis without a prescription
tadalafil prix
liquid ivermectin
stromectol medicine
order ivermectin for humans
intermectine
psy-
psy-
projectio
projectio
moskva psiholog online
moskva psiholog online
slovar po psihoanalizu laplansh
slovar po psihoanalizu laplansh
psy online
psy online
uels ukrain
uels ukrain
order stromectol online
stromectol online canada
DPTPtNqS
DPTPtNqS
qQ8KZZE6
qQ8KZZE6
D6tuzANh
D6tuzANh
SHKALA TONOV
SHKALA TONOV
Øêàëà òîíîâ
Øêàëà òîíîâ
russianmanagement.com
russianmanagement.com
chelovek-iz-90-h
chelovek-iz-90-h
3Hk12Bl
3Hk12Bl
3NOZC44
3NOZC44
01211
01211 21546
tor-lyubov-i-grom
tor-lyubov-i-grom
film-tor-2022
film-tor-2022
hd-tor-2022
hd-tor-2022
hdorg2.ru
hdorg2.ru
ivermectin for scabies
ivermectin 3mg tab
Psikholog
Psikholog
netstate.ru
netstate.ru
Link
Link
iver mectin
ivermectin treatment
buy ivermectin
ivermectin oral