Многие компании на своих должностях разработчиков требуют от специалистов знания SOLID. Однако многие считают, что это просто набор практических приемов во время разработки, но не знают теории, стоящей за этим.
Принципы S.O.L.I.D., аббревиатура с инициалами принципов, обсуждаемых ниже, предназначены для организации функций и структур данных таким образом, чтобы облегчить разработку и эволюцию программного обеспечения. Целью этих принципов является создание кода, который устойчив к изменениям, прост для понимания и является основой компонентов, которые могут быть использованы в нескольких системах.
S — Принцип единой ответственности (SRP)
O — Принцип открытого закрытия (OCP)
L — принцип замещения Лискова (LSP)
I — Принцип разделения интерфейсов (ISP)
D — Принцип инверсии зависимостей (DIP)
Каждый из вышеперечисленных принципов будет подробно рассмотрен ниже.
ПСО: Принцип единой ответственности
Этот принцип показывает, что класс должен быть специализирован на одном предмете и иметь только одну ответственность. Другими словами, класс должен выполнять одно действие.
MARTIN (2017) переформулирует общепринятое описание, что модуль должен иметь только одну причину для изменения, и утверждает, что SRP следует описывать как модуль, который должен отвечать только за одного актора. Этот актор представляет пользователя или заинтересованную сторону, которые являются «причиной для изменений» первоначального определения. Термин модуль можно определить как исходный файл или целостный набор функций и структуры данных.
Нарушение этого принципа может привести к тому, что класс возьмет на себя несвойственные ему обязанности, повысит уровень связанности, создаст трудности при проведении автоматизированных тестов и затруднит повторное использование кода.
OCP: Принцип открытости/закрытости
Этот принцип был создан Бертраном Мейером (1997) и гласит, что программное обеспечение должно быть открытым для расширения, но закрытым для модификации. То есть, когда в систему необходимо добавить новые возможности, ее следует расширить, а не изменять исходный код.
Согласно MARTIN (2017), OCP является одной из движущих сил в архитектуре системы, и этот принцип является самым важным из объектной ориентации. Для того чтобы достичь цели — сделать систему легкой и не допустить, чтобы это изменение вызвало серьезные последствия, необходимо разделить систему на компоненты. Эти компоненты организованы в иерархию зависимостей, чтобы защитить компоненты высокого уровня от изменений, внесенных в компоненты более низкого уровня.
LSP: Принцип замещения Лискова
Принцип подстановки Лискова был определен Барбарой Лисковой и расскрывает использование свойства подстановки в качестве основы. Это свойство описывается демонстрацией:
если для каждого объекта o1 типа S существует объект o2 типа T, такой, что для всех программ P, определенных в терминах T, поведение P не меняется при замене o1 на o2, то S является подтипом T. (MEYER, 1997).
Другими словами, LSP говорит, что если S является подтипом T, то объекты типа T в программе могут быть заменены объектами типа S без необходимости изменения свойств этой системы.
LSP стал более широким принципом паттерна проектирования и может применяться к интерфейсам и реализациям. Этот принцип говорит нам, что реализации должны подчиняться какому-то договору. Применение LSP важно, поскольку пользователям нужны хорошо определенные интерфейсы и возможность замены реализации интерфейсов. Этот принцип следует применять и к архитектуре, учитывая, что нарушение в способности замещения может загрязнить архитектуру системы большим количеством дополнительных механизмов (MARTIN, 2017). Некоторые примеры того, что может произойти при нарушении этого принципа, следующие:
- выбросить неожиданное исключение;
- переопределить или реализовать метод, который ничего не делает;
- возвращают значения различных типов из базового класса.
ISP: Принцип разделения интерфейсов
Этот принцип показывает, что класс не должен быть вынужден реализовывать интерфейсы и методы, которые он не собирается использовать, то есть лучше создавать более специфические интерфейсы, чем иметь один большой общий интерфейс. Классы не должны зависеть от того, что им не нужно.
Этот принцип используется в архитектуре, чтобы избежать зависимостей модулей с большим количеством ненужных элементов. Это справедливо как на более высоких, так и на более низких архитектурных уровнях, поскольку, например, зависимости исходного кода могут без необходимости заставлять перекомпилировать и переразвертывать систему.
DIP: Принцип инверсии зависимостей
О принципе инверсии зависимостей, MARTIN (2017) показывает, что наиболее гибкими системами являются те, в которых зависимости исходного кода относятся только к абстракциям, а не к конкретным элементам.
В целом, это говорит о том, что ни один класс или функция не должны быть озабочены тем, как делается определенная вещь. Некоторые классы, например, класс String, являются конкретными, поэтому было бы неинтересно заставлять их быть абстрактными. Однако эти классы очень стабильны, поэтому изменения в них происходят очень редко и контролируются, так что вам не нужно беспокоиться об этих изменениях. Бетонные классы терпимы, потому что вы знаете, что они не изменятся.
Применяя Чистую архитектуру, модули высокого уровня не должны зависеть от модулей низкого уровня, оба должны зависеть от абстракции. Абстракции не должны зависеть от деталей, скорее детали должны зависеть от абстракций.
Заключение
SOLID — это не просто еще одна строчка в требованиях компаний при поиске профессионалов, это необходимый набор лучших практик.
Когда эти принципы применяются к системам, они становятся более структурированными, целостными и более гармоничными, что является основополагающим для чистой архитектуры.
Каждый хороший специалист должен стремиться углубить свои знания о принципах SOLID, применять их в своей повседневной работе и распространять их среди своих команд. Необходимо распространять и применять передовой опыт.
Ссылки
- МАРТИН, Роберт К. Чистая архитектура: руководство ремесленника по структуре и дизайну программного обеспечения. 1-е изд. США: Prentice Hall Press, 2017. ISBN 0134494164.
- Мейер, Бертран. Объектно-ориентированное построение программного обеспечения. 2. изд. Upper Saddle River, NJ: Prentice Hall, 1997. ISBN 978-0-13-629155-8.