5. DIP (Dependency inversion principle) - Принцип инверсии зависимостей

Принцип инверсии зависимостей (англ. Dependency Inversion Principle, DIP) — важный принцип объектно-ориентированного программирования, используемый для уменьшения связанности в компьютерных программах. Входит в пятёрку принципов S.O.L.I.D.

Формулировка:

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

Принцип может показаться раздутым ,но он очень простой для понимания. Этот принцип обеспечивает разделение, но думаю лучше объяснять на примере:

class PasswordReminder {
     private $dbConnection;
 
     public function __construct(MySQLConnection $dbConnection) {
         $this->dbConnection = $dbConnection;
     }
}

MySQLConnection является низкоуровневым модулем, PasswordReminder - высокоуровневый. Но в соответствии с определением принципа, гласящим разделять абстракции от реализации, этот фрагмент его нарушает, т.к. класс PasswordReminder зависит от класса MySQLConnection.

Если позже изменить ядро базы данных, то прийдется менять и класс PasswordReminder, что нарушает принцип открытости / закрытости.

Класс PasswordReminder не должен беспокоиться об используемой СУБД. Для исправления этого мы должны выделить интерфейс, чтобы низкоуровневые и высокоуровневые модули зависели от абстракции:

interface DBConnectionInterface {
     public function connect();
}

Интерфейс имеет метод connect и класс MySQLConnection реализует его. Также вместо проверки типа на пренадлежность передаваемого объекта классу MySQLConnection в конструкторе PasswordReminder, мы используем проверку принадлежности интерфейсу. И класс PasswordReminder больше не беспокоится о типе СУБД, которая будет использована, главное, что есть возможность соединения и принцип OCP не нарушается.

class MySQLConnection implements DBConnectionInterface {
     public function connect() {
         return "Database connection";
     }
}
 
class PasswordReminder {
     private $dbConnection;
 
     public function __construct(DBConnectionInterface $dbConnection) {
         $this->dbConnection = $dbConnection;
     }
}

Теперь оба модуля (низкоуровневый и высокоуровневый) зависят от абстракции.

Теги: Solid, Dip, Dependency inversion principle, Принцип инверсии зависимостей


Похожие статьи

1. SPR (Single responsibility principle) - Принцип единственной обязанности

4. ISP (Interface segregation principle) - Принцип разделения интерфейса

2. OCP (Open/closed principle) - Принцип открытости/закрытости

3. LSP (Liskov substitution principle) - Принцип подстановки Барбары Лисков