SOLID принцины

SOLID принцины


freelanceland
Лучшие исполнители для ваших задач

Single responsibility (SRP) - принцип единой ответственности

- объект должен отвечать только за что-то одно и эта ответственность должна быть инкапсулирована в класс. Классы должны иметь одну и только одну причину для изменений.

Примеры использования SRP

- есть класс Order, в котором есть функционал отвечающий за работы с заказами и печать заказов. Следует разбить на 2 класса: Order и OrderPrint.

Когда стоит использовать SRP

- любое изменение логики поведения объекта приводит к изменениям в других местах приложения, где это не подразумевалось изначально
- невозможно легко отделить и применить класс в другой сфере приложения, так как это потянет ненужные зависимости
- объекту класса становится позволительно слишком много

Шаблоны использующий принципы SRP

- Разработка через тестирование
- Шаблон «Выделение класса»
- Шаблон «Фасад»
- Шаблон «Proxy»
- DAO


Open-Closed (OCP) - открытости и закрытости

- классы должны быть открыты для расширения (добавление нового поведения), и закрыты для изменения, т.е при добавлении поведения класса, логика в нем не должна меняться. Следует унаследовать от текущего класса или интерфейса и добавить функционал.

Примеры использования OCP

- имеется класс Logger, который пишет логи в файл. Требуется расширить функционал, что бы логи писались в БД. Правильной реализацией будет создание общего интерфейса ILogger и наследование от него: FileLogger и DbLogger.


Liskov Substitution (LSP) - принцип подстановки

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


Interface Segregation (ISP) - разделение интерфейсов

- слишком «толстые» интерфейсы необходимо разделять на более маленькие, чтобы наследники маленьких интерфейсов знали только о методах, которые необходимы им в работе
- классы которые реализуют интерфейс не должны зависеть от методов которых не реализуют


Dependency Inversion (DIP) - инверсия зависимости

- Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций.
- Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

Примеры использования DIP

- имеется класс PasswordReminder который ожидает объект MySQLConnection. PasswordReminder - высокоуровневый класс, а MySQLConnection - низкоуровневый. В случае изменения БД, потребуется изменение во многих местах в том числе и в PasswordReminder, что нарушает принцип открытости/закрытости. Для соблюдение принципов, нужно MySQLConnection унаследовать от интерфейса IDbConnection, а в PasswordReminder ожидать экземпляр интерфейса IDbConnection вместо MySQLConnection.
        
            interface IDbConnection {
                 public function connect();
            }

            class MySQLConnection implements IDbConnection {
                 public function connect() {
                     return "Database connection";
                 }
            }

            class PasswordReminder {
                 private $dbConnection;

                 public function __construct(IDbConnection $dbConnection) {
                     $this->dbConnection = $dbConnection;
                 }
            }
        
    
Теперь оба модуля (низкоуровневый и высокоуровневый) зависят от абстракции.


Читайте также: Принципы программирования

Также читают

sql: Как получить последнюю запись в каждой группе с помощью GROUP BY?
Закон Деметры
Шпаргалка Git команд

Возврат к списку