Что говорят SOLID принципы?

SOLID — аббревиатура, объединяющая 5 принципов:

S - The Single Responsibility Principle (SRP) - принцип единственности ответственности

Принцип единственности ответственности или принцип единственности обязанности заключается в том, что класс (объект) должен выполнять строго одну задачу, иметь одну зону ответственности. Объект должен выполнять свою задачу очень хорошо, другие объекты не должны отвечать за эту задачу вовсе. Нужно сказать, что не всем такое определение нравится.

По книжке Дяди Боба (Роберта Мартина), классическое определение Single Responsibility принципа — одна и только одна причина может быть для изменения модуля или класса. Модуль или класс должен отвечать перед одним и только одним актором.

Чтобы следовать принципу SRP — нужно грамотно применять декомпозицию. Декомпозировать так, чтобы не было сложных классов, которые отвечают сразу за несколько вещей, чтобы сложные классы разбивались на более специализированные простые.

O - The Open Closed Principle (OCP) - принцип октрытости/закрытости

Программные сущности должны быть открыты для расширения, но закрыты для модификации.

Открыты для расширения означает, что новые сущности могут создаваться путём создания новых типов сущностей. Мы можем изменять поведение (реализацию) существующих сущностей.

Закрыты для модификации означает, что при расширении сущности не должна быть необходимость изменять код, который работает с этой сущностью.

Мы можем менять класс делая баг фиксинг или мелкие изменения, но не можем переопределить функцию или создать новую, так как придется менять код, который работает с этой сущностью. Чтобы соблюдать OCP, нужно работать через интерфейсы и делать зависимости на основе интерфейсов. Тогда клиенту будет абсолютно все равно на то, что мы начали использовать новую реализацию, потому-что клиент зависит не от сущности напрямую, а от интерфейса. Если спроектировали все верно - меняться будет только реализация интерфейса и никак не код который работает с этим интерфейсом.

Создание дочерних элементов не должно приводить к изменению родительского кода.

L - Liskov substitution - принцип подстановки

Объекты могут быть заменены экземплярами их подтипов (наследниками) без изменения правильности выполнения программы.

Примеры нарушения принципа — 

В php 7.4 — можно нарушить этот принцип. В дочерних классах можно изменять типизация родительских функций безнаказанно, их стало можно сужать.

Почему это разрешили в php 7.4? Разработчик теперь может сам решать, должнен ли соблюдаться принцип подстановки. А код позволяет сделать все.

Есть класс A c public свойством public $a; Если мы меняем область видимости на более строгую protected $a;, то мы получим Exception.

I - Interface Segregation Principle - принцип разделения интерфейсов

Лучше иметь множество конкретных интерфейсов, чем один общий.

Интерфейс - для внешнего взаимодействия. Если интерфейс переусложненный, то взаимодействовать с ним тяжелее. Встает вопрос, нужны ли нам такие зависимости.

D - Dependency Inversion Principle - принцип инверсии зависимостей

Абстракции не должны зависеть от деталей реализации. Реализация должна зависеть от абстракций. На практике это означает, что модули верхних уровней не должны зависеть от модулей нижних уровней. Все модули должны зависеть от абстракций.

Есть очень простой пример, позволяющий понять принцип. Например, есть сущность комментарий. Для сохранения комментария нам нужно соединение с базой данных. Так вот, если для сохранения комментария мы будем передавать mysqli_connection или pdo_connection или еще что-то в этом роде - то мы нарушим принцип инверсии зависимостей. Соединение с базой данных - в данном случае модуль низкого уровня. А комменатрий - модуль верхнего уровня. Таким образом для сохранения комментария нам нужно передавать абстрактный коннекшен, то есть интерфейс.

Комментарий не должен напрямую зависить от конкретного соединения, а должен завить от абстрактного DbConnection (это интерфейс). При следовании принципу инверсии зависимостей, если мы поменяем используемую базу данных c MySQL на PostgreSQL или другую, то нам не придется в классе, сохраняющем комментарий, менять реализацию. Комментарий продолжит сохраняться, а мы подменим только реализацию DbConnection.

 
 
 

icon Комментарии 0

Ваш комментарий к статье.. (для авторизованных)

ctrl+enter

icon Вход в систему

зарегистрироваться