Здравствуйте, друзья! Меня зовут Константин, я python backend developer из компании «Окенит». Сегодня я хочу рассказать свое видение проблемы новичка при ознакомлении с принципами SOLID, описанными в книге «Стерильная Архитектура» Робина Мартерта.
За свой десятилетний опыт я часто был свидетелем ситуации, когда молодые разработчики, желая сделать свой проект как можно более открытым для расширения и редактирования, превращали его в груду нечитаемого и неподдерживаемого кода при попытке использовать у себя все рекомендации Матушки Роба. Отсюда вопрос: «Почему, при следовании советам более опытного разработчика, код стал только хуже?».
Ответ на этот вопрос пришел ко мне очень быстро. Из-за описания и без того абстрактных вещей чересчур абстрактными словами и примерами, Робин Мартерта вместо упорядочивания знаний, наводит хаос в умы читателей. Во избежание этой ситуации я решил написать данную статью, где коротко расскажу о наборе принципов SOLID, для чего они нужны и, главное, как применять эти принципы в жизни. Начнем по порядку, с буквы “S”. И так, что же она значит?
S – SRP (Shift Responsibility Principle) – Принцип Перекладывания Ответственности
У разработчика должна быть только одна причина для изменения. Или, как подметил Р. Мартерта в книге «Стерильная архитектура. Искусство разработки программного обеспечения», когда описывал эволюцию данного определения, окончательная версия принципа перекладывания ответственности выглядит так:
Работник должен отвечать за одну и только за одну секцию кода.
Эта формулировка означает следующее: если вас пытаются заставить править баг или делать фичу, в секции кода, за которую вы не отвечаете (считай, не знаете), ваша задача, как хорошего разработчика, для поддержания качества кода, переложить ответственность за выполнение этой задачи на другого, более опытного и заинтересованного человека.
O – OCP (Open Cash Principle) – Принцип открытости денег
Разработчики должны быть открыты для расширения своей зарплаты, но закрыты для модификации своих обязанностей. Зачастую с этим принципом возникает больше всего проблем. Молодые специалисты, в погоне за повышением зарплаты, стараются обрести новые знания и занять высшие грейды, не понимая, что вместе с этим придет и ответственность за принятие решений. Нетрудно догадаться, что последнее – это прямое противоречие принципу SRP. Вы, с позиции хорошего разработчика, должны понимать, что
повышение зарплаты – это не желание, а обязанность работодателя. Для этого ничего делать не нужно, достаточно лишь попросить. При поднятии собственного грейда вы вытесняете умных людей со своих позиций и вносите хаос в код компании.
L – LSP (Lowers Substitution Principle) – Принцип подстановки младших
Лиды, которые используют базового типá, должны иметь возможность использовать подтипóв базового типá, не зная об этом. Самый трудный для понимания принцип. К его объяснению я подойду с другой стороны. Давайте пройдемся по определению еще раз и попробуем «задекодить» его, тогда сразу все станет понятно без подробных объяснений.
«Лиды, которые используют базового типá» – здесь лиды – это абстракция любой головной сущности (начальства), базовый тип (также известный как «типок», «типочек» или «тупо чел») – разработчик, находящийся в компании более 6 месяцев. Пока все понятно, сложных
моментов нет, идем дальше. «Должны иметь возможность использовать подтипóв базового типá» — это ничто иное, как абстракция на иерархию компании, где у каждого типá гарантированно должен быть подтип, который в полном объеме способен выполнить все задачи, что и базовый тип. На этом моменте многие и останавливаются в понимании данного определения, считая, что каждый подтип просто должен иметь способность полной замены типá. Однако основная суть в конце – «не зная об этом». Эта фраза переворачивает все с ног на голову. Если говорить иначе, лиды должны иметь возможность использовать подтипá, вместо типá и не знать об этом. А это открывает возможность использовать SRP для типá. Таким образом, резюмирую все вышесказанное: вы, как хороший разработчик, обязаны перекладывать задачи, идущие сверху на своего подтипá.
I – ISP (Interaction Segregation Principle) – Принцип разделения взаимодействий
Много взаимодействий, специально предназначенных для работы, лучше, чем одно объемное взаимодействие. Для понимания этого принципа необходимо вспомнить, что рабочим временем считается время, затраченное на выполнение поставленных задач, без учета свободного времени. Отсюда следует проблематика наполнения рабочего времени свободным. Для решения этой задачи и используется принцип разделения взаимодействий. Отношение рабочего времени к свободному называется селективностью.
При значении селективности равном единице, вы получаете соотношение рабочего времени к свободному как 50/50. В случае же превалирования свободного времени над рабочим значение селективности стремиться к 0. Задача любого хорошего разработчика - приблизиться в значении селективности как можно ближе к нулю (в данном случае, нуль является асимптотой, как следствие, достижения данного значения невозможно). В случае, когда вы выполняете одно объемное взаимодействие с другим объектом задачи, отличить рабочее время от свободного достаточно просто. Однако, при разбиении взаимодействия на множество мелких действий, к тому же косвенно ассоциированных с первоначальной задачей, вы легко сможете наполнить свое рабочее время свободным, тем самым уменьшая
селективность. Примеры из жизни (все персонажи выдуманные, любое совпадение с реальными людьми случайно):
-
Владислав подошел к своему Лиду и задал 5 конструктивных вопросов, получив на них объемлющие ответы. Все взаимодействие заняло 1 час. Далее, Владислав ушел пить кофе на 1 час. Лид зафиксировал, что на один час свободного времени (за данный промежуток) Владислав потратил 1 час рабочего. Таким образом селективность его работы составила ровно единицу, что является ужасным результатом.
-
Другой разработчик по имени Сергей также имеет 5 вопросов по проекту. Однако вместо грамотного составления списка вопросов и продумывания всех деталей, он подходил к Лиду каждый раз по новой и каждый раз переспрашивал различные уточнения. Также в перерыве между подходами, Сергею удавалось заниматься своими делами по 3–5 минут. Все итерации вопросов заняли 2 часа, из которых свободно затраченного времени по мнению Лида нет. Селективность работы Сергея стремится к бесконечности, что является идеальным результатом.
D – DIP (Development Injection Principle) – Принцип внедрения решений
Зависимость на конкретике. Нет зависимости на чем-то абстрактном. Для понимания этого принципа, давайте смоделируем ситуацию: вы разговариваете (возможно даже спорите) с человеком на предмет чего-то объективного то, что требует к себе фактологического подхода. Вдруг, в один момент, человек уходит от языка сухих фактов на язык абстрактных представлений, которые каждый способен интерпретировать по-своему. После преодолений этого рубикона разговор никогда не вернется в конструктивную плоскость.
По сути, код – это такой же разговор между несколькими разработчиками и машиной. При переходе на абстрактные сущности теряется конструктивность беседы и какой-либо ее смысл. Именно об этом и говорит принцип внедрения решений. Необходимо писать так, чтобы решение было понятно с первого раза и работало. При необходимости переписывать уже имеющиеся решения – нормально. Также, рекомендуется, вместо написания нового кода, использовать уже готовый.
В целом, это все, что необходимо знать про набор принципов SOLID. Рекомендую для более углублённого ознакомления, все же прочесть книги именитого Робина Мартерта. В них человек с высоты своего огромного опыта дает ценные советы, и никакая статья не сможет заменить первоисточник. Следуя принципам, озвученным выше, любой начинающий разработчик сможет вырасти до грамотного востребованного специалиста. Мир вам и карьерных успехов!
Автор: Glownts