
SOLID. Что значит S
Давайте поговорим о том, что такое SOLID? Наверняка вы читали книгу «Чистый Код» Роберта Мартина (как это не читали???) и вам уже давно известно, что это такое. Да и в интернете есть множество статей на эту тему. Однако же, мне, как и большинству других разработчиков, постоянно приходится работать с грязным кодом, который можно улучшить. Возникает парадокс – если все знают правила написания хорошего кода, откуда берется код плохой? В следующем блоке постов я хочу кратко рассказать, как я понимаю каждый из принципов SOLID, и, что самое главное – как мне это помогает писать более понятный и чистый код. Никаких научно-занудных объяснений. Все максимально просто, кратко и на примерах. Сегодня поговорим о том, что значит S в аббревиатуре SOLID.
S значит SRP
А SRP значит Single-Responsibility Principle. Что, в свою очередь, переводится как «принцип единой ответственности». Занудное и чисто теоретическое (но более полное) описание этого принципа можете прочитать на википедии.
SRP на примере. Аркадий в деле
Итак, у нас есть класс Employee:
public class Employee {}
Разработчик Аркадий смотрит-смотрит на этот класс и не понимает, а чего он пустой-то? Ну и решает он добавить метод writeCode()
(реализация опущена):
public void writeCode() {
// ...
}
Немного подумав и почесав затылок, Аркадий исправляет название метода на writeGoodCode()
. Потому что Аркадий — хороший разработчик!
Иннокентий негодует
Тестировщик Иннокентий, проходя мимо рабочего стола Аркадия, бросает быстрый взгляд на его монитор и замечает, что Employee
только пишет код и совсем не тестирует его.
«Ну ты, Аркаша, и растяпа», – замечает Иннокентий и просит последнего исправить ситуацию. Аркадий соглашается и добавляет соответствующий метод (реализация снова опущена):
public void test() {
// ...
}
Довольный Иннокентий с чувством выполненного долга уходит в закат. И вроде бы все хорошо, но тут…
Появляется Савелий Петрович
А Савелий Петрович, между прочим, менеджер проекта. И, как оно обычно и бывает, он коршуном налетает на бедного Аркадия и просит его «добавить фичку для клиента» в обход спринта. Внезапно Савелий Петрович замечает, что класс Employee
совсем не занимается управлением командой, и просит добавить аж ТРИ метода.
Вспотевший Аркадий добавляет в класс Employee
:
public void planSprint() {
// ...
}
public void addLittleFeature() {
// ...
}
public void manage() {
// ...
}
Савелий Петрович вдруг замечает тестировщика Иннокентия, и фокус его внимания быстро съезжает с нашего бедного Аркадия. Казалось бы, можно передохнуть, но внезапно…
Приходит Люська из аналитики
И вот в класс Employee
добавляется Люськин метод:
public void analyze() {
// ...
}
А затем…
Появилась ОНА. Аксинья Всеволодовна из отдела уборки. «А полы мыть кто будет?» – Грозно прорычала она, отобрала у Аркадия компьютер и самовольно добавила:
public Garbage cleanUp() {
// …
}
Аркадий, слегка придя в себя, робко спросил: «А зачем метод уборки что-то возвращает? Почему он не void?». Аксинья Всеволодовна будто ждала этого вопроса и гаркнула еще громче: «Да чтоб вы свой мусор все обратно получили, собаки вы сутулые!»
Что в итоге?
А в итоге класс Employee
выглядит следующим образом:
public class Employee {
public void writeGoodCode() {
// ...
}
public void test() {
// ...
}
public void planSprint() {
// ...
}
public void addLittleFeature() {
// ...
}
public void manage() {
// ...
}
public void analyze() {
// ...
}
public Garbage cleanUp() {
// ...
}
}
Похоже на SOLID? Как вам SRP?
Кто-то скажет, что Employee
– типичный fullstack, который умеет делать все на свете. Однако, задумайтесь, нужен ли вам такой fullstack?
Чем это чревато?
Допустим, уборщица Аксинья Всеволодовна прошла курсы по повышению квалификации, и теперь ей доступна тряпка более высокого уровня. Вследствие этого, мы с вами идем в класс Employee
и меняем реализацию метода cleanUp()
.
А затем наш разработчик Аркадий резко встал со своего места, воскликнул: «Да ну нах*р!» и удалился восвояси. Заместо него пришел другой разработчик, Акакий, который уже не такой опытный и пишет не такой хороший код. Поэтому мы снова идем в класс Employee
и меняем название метода writeGoodCode()
на writeCode()
.
А ведь у нас есть еще тестировщик Иннокентий, аналитик Люська и менеджер проектов Савелий Петрович – помните? Если хоть что-то деталях их работы изменится, нам снова нужно будет идти в класс Employee
.
В общем, ребята, наш супер-класс на самом деле является вонючей помойкой, куда не навалил всякой логики только лентяй. Надо ли нам поменять метод уборки помещения или же метод написания кода – мы лезем в этот класс. Поменять метод тестирования? Снова в этот класс.
Представьте, что Employee
– это вы, и ваш основной профиль – разработка. Вот вы сидите, пишете код, и тут приходит менеджер проектов и говорит: «Спланируй спринт на следующую неделю». Потом приходит аналитик и говорит: «Сделай спеку по такой-то задаче, а потом сам по ней напиши код». И под конец рабочего дня приходит уборщица: «Там унитаз засорился, а у тебя пальцы-то гибкие, иди прочисть».
И вы просто не понимаете, зачем вы должны все это делать, ведь у вас конкретный и узкий профиль. Так же и Employee
не понимает, зачем вы пихаете в него все, что не лень.
Как итог – у этого класса нет единой области ответственности, и он берет на себя слишком много. SOLID и особенно SRP тихонько негодуют в сторонке. Задачи (методы), описанные в этом классе, по-хорошему должны быть распределены на весь отдел. Давайте теперь посмотрим, как все должно быть по уму.
И тут приходит Здравый Смысл
И тут же падает в обморок от увиденного. Но уборщица Аксинья Всеволодовна выливает на него ушат холодной и грязной воды, и Здравый Смысл приходит в себя.
Он говорит: «Ребята, у вас тут не соблюдается принцип единой ответственности, также известный как SRP» и тут же начинает исправлять ситуацию и делать код более SOLID.
Метод, который отвечает за написание кода, он выносит в класс Developer
:
public class Developer {
public void writeCode() {}
}
Немного подумав, Здравый Смысл замечает, что Developer
должен еще и фиксить баги, поэтому он добавляет новый метод в тот же класс Developer
:
public class Developer {
public void writeCode() {}
public void fixBug() {}
}
«Отлично!», – восклицает Савелий Петрович, – «Теперь вся логика по разработке и багфиксу сосредоточена в одном месте!»
Здравый Смысл согласно кивает и создает класс ProjectManager
:
public class ProjectManager {
public void planSprint() {}
public void addLittleFeature() {}
public void manage() {}
}
Немного погодя, он удаляет метод addLittleFeature()
, и Савелий Петрович в слезах удаляется. Но это уже тема для отдельного разговора.
Здравый Смысл, тем временем, не отдыхает и создает новые классы:
public class Tester {
public void test() {}
}
public class Analyst {
public void analyze() {}
}
public class Cleaner {
public void cleanUp() {}
}
Что стало лучше?
Здравый Смысл сажает всех вокруг себя и говорит следующие золотые слова:
– Теперь у каждого из вас есть своя зона ответственности. Акакий, если тебе нужно будет добавить новый метод или изменить существующий, ты пойдешь в класс Developer
. И тебя больше не будут просить прочистить унитаз! Иннокентий, ты у нас теперь только тестируешь, и твой класс называется Tester
. Люська сидит в Analyst
, поэтому для изменений в ее работе вам следует отправиться именно туда. Савелий Петрович, ваша работа теперь заключена в классе ProjectManager
, и никаких больше маленьких фич! Ну а вы, уважаемая Аксинья Всеволодовна, теперь сосредоточены в Cleaner
, и не смейте больше свои обязанности скидывать на бедного Акакия! Давайте соблюдать SRP! У каждого из вас теперь своя зона ответственности!
Все встают и отправляются заниматься своей работой.
И это далеко не все
Представьте, что Здравый Смысл не приходил, и наш класс Employee
по-прежнему выглядит ужасающе.
И вдруг случается так, что уборщица в офисе этажом выше приболела, и они попросили на время нашу Аксинью Всеволодовну. А она, на самом-то деле, добрейшей души бабка, и не может отказать людям в беде.
А так как она часть Epmloyee
, то она заодно хватает с собой всех остальных: Акакия, Иннокентия, Люську и Савелия Петровича. И вот они приходят в офис этажом выше. Аксинья Всеволодовна приступает к работе, а остальные стоят вдоль стены и молча смотрят.
А теперь давайте перейдем к коду. Допустим, есть класс Office
, и ему необходим только один метод: cleanUp()
.
Выглядит он как-то так:
public class Office {
private final Employee employee;
public Office(Employee employee) {
this.employee = employee;
}
public void cleanUp() {
employee.cleanUp();
}
}
Возникает вопрос – если классу нужен лишь один метод cleanUp()
, зачем ему объект, который, кроме этого метода, содержит еще кучу других, никак с уборкой не связанных? Иными словами, руководство офиса недоуменно смотрит на Акакия, Иннокентия, Люську и Савелия Петровича, которые как идиоты стоят у стены и смотрят, как Аксинья Всеволодовна убирается.
Вот как бы выглядел класс Office после визита Здравого Смысла:
public class Office {
private final Cleaner cleaner;
public Office(Cleaner cleaner) {
this.cleaner = cleaner;
}
public void cleanUp() {
cleaner.cleanUp();
}
}
Просили уборщицу – пришла уборщица. Одна. Без кучи лишних зависимостей. Все ясно и понятно.
Вывод
Следуй здравому смыслу. Не нарушай SRP.
Понравилось? Подписывайтесь на меня в соцсетях!


The Best Premium IPTV Service WorldWide!
A person essentially assist to make seriously posts I would state. That is the very first time I frequented your website page and thus far? I surprised with the analysis you made to create this particular publish extraordinary. Excellent process!
I will immediately clutch your rss as I can’t to find your email subscription hyperlink or newsletter service. Do you have any? Please permit me understand in order that I could subscribe. Thanks.
you are in reality a excellent webmaster. The website loading velocity is incredible. It seems that you are doing any unique trick. In addition, The contents are masterwork. you have performed a magnificent task on this topic!
Excellent blog here! Also your web site loads up very fast! What web host are you using? Can I get your affiliate link to your host? I wish my site loaded up as quickly as yours lol
Excellent web site. Lots of useful information here. I’m sending it to a few pals ans additionally sharing in delicious. And obviously, thank you to your effort!
BpOUz6ggluY
FivFoU9Xj25
wVwDjhdEh3a
6NHxfho7PJs
ynEDg94XLE2
2NP8qsAzZ1V
ydx3fuNl6eK
5boXdb5NirI
syvt1lR3Z95
966s5Re5O6I
CiQh6ixdKEl
eee7xWv9IFl
E6iMZItU2nc
sEzAxiSvbtW
X5fG2gnw7MQ
90UxVMn9RIh
eVkUyh8fdzA
tbdYdJOPIos
R0Z5KxkSMso
FXG0wjvoQ3d
DmNGojaNY1t
qVxyiiesO4z
86NttkVQEWQ
QpIr1rF6JrW
dgtiKKzdnqT
SuDOZsacdZU
qnmBkYKe8DC
1KIpGXmytkc
G5IzAc3ZcwX
HKowE6GTVhd
UBuM7ck9Jzm
8BLLmNhG11f
2JRQEIFPa16
16eI5EazD06
37SnjGvcYIF
1nR5eFlqBD2
MsOZcjboSC3