SOLID principles in php

SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 5 Принцип на обръщане на зависимостите – DIP

Част 1 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 1 Принцип на единна отговорност

Част 2 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 2 Принцип отворено-затворен

Част 3 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 3 Принцип на заместване на Лисков

Част 4 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 4 Принцип за разделяне на интерфейсите – ISP

Част 5 – SOLID: Първите 5 принципа на обектно ориентиран софтуерен дизайн, част: 5 Принцип на обръщане на зависимостите – DIP

Принципът на обръщане на зависимостите – DIP гласи:

модулите на по-високо ниво не зависят от тези на по-ниско ниво, като и двата трябва да зависят само и единствено от абстракции. В същото време абстракциите не трябва да зависят от детайлите, а детайлите трябва да зависят от абстракциите

Този принцип е въведен от Роберт Мартин.

Този принцип позволява разделяне.

Ето пример за a, PasswordReminder който се свързва с MySQL база данни:

class MySQLConnection
{
    public function connect()
    {
        // handle the database connection
        return 'Database connection';
    }
}

class PasswordReminder
{
    private $dbConnection;

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

Първо, MySQLConnection модулът е ниско ниво, докато PasswordReminder е високо ниво, но според дефиницията на D в SOLID, която гласи да зависи от абстракцията, а не от конкрементите . Този фрагмент по-горе нарушава този принцип, тъй като PasswordReminder класът е принуден да зависи от MySQLConnection класа.

По-късно, ако трябваше да промените двигателя на базата данни, ще трябва да редактирате и PasswordReminder класа и това ще наруши принципа отваряне-затваряне .

PasswordReminder класа не трябва да се интересува какви база данни са вашите нужди за кандидатстване. За да разрешите тези проблеми, можете да кодирате към интерфейс, тъй като модулите на високо и ниско ниво трябва да зависят от абстракцията:

interface DBConnectionInterface
{
    public function connect();
}

Интерфейсът има метод за свързване и MySQLConnection класът реализира този интерфейс. Освен това, вместо директно да намеквате MySQLConnection класа в конструктора на PasswordReminder, вие вместо това пишете DBConnectionInterface и без значение какъв тип база данни използва вашето приложение, PasswordReminder класът може да се свърже с базата данни без никакви проблеми и принципът отваряне-затваряне не се нарушава .

class MySQLConnection implements DBConnectionInterface
{
    public function connect()
    {
        // handle the database connection
        return 'Database connection';
    }
}

class PasswordReminder
{
    private $dbConnection;

    public function __construct(DBConnectionInterface $dbConnection)
    {
        $this->dbConnection = $dbConnection;
    }
}

Този код установява, че модулите на високо и ниско ниво зависят от абстракцията.

Традиционен модел

В конвенционалната архитектура на дадено приложение, компонентите на ниско ниво са проектирани за да бъдат консумирани от тези на по-високо ниво. При това съставяне на слоевете, компонентите на високо ниво зависят директно на тези на по-ниско ниво за да извършат дадена задача. Тази зависимост върху компонентите на ниско ниво ограничават възможността за преизползване на компонентите на по-високо ниво. Традиционният модел се използва, когато програмиста не го интересува дали в бъдеще кодът ще се разширява, а просто иска да заработи със сегашната си функционалност. Това разбира се е грешно.

Целта на принципа за обръщане на зависимостите, е да избегне свързаността между модулите, като се ползва абстрактен модул за посредник между двата компонента. Това увеличава преизползваемостта и взаимозаменяемостта на модулите на по-високо ниво, като проекта става по-лесен за разширяване и по-гъвкав.

Правила за обръщане на зависимостите

  • Класовете трябва да декларират от какво имат нужда.
  • Скритите зависимости трябва да бъдат показани.
  • Зависимостите трябва да са абстракции.

Начини за обръщане на зависимостите

  • През конструктора Този начин е добър, защото за да създадем инстанция на даден обект, ние ще трябва да подадем през конструктора всичките зависимости от които се нуждае обекта, и ако съответно пропуснем да подадем някой, няма да можем да създадем желаният обект. По този начин класът документира в конструктора си от какво се нуждае за да работи и няма скрити зависимости. Друг плюс е, че класът винаги ще бъде във валидно състояние, защото няма как да не подадеш някоя зависимост в конструктора и да създадеш обекта без нея. Недостатъците на този метод са: Това води до въвеждането на много параметри, когато се инстанцира съответния клас. Някои от методите няма да се нуждаят от абсолютно всички параметри подадени в конструктора.
  • През пропъртитата Предимствата на този метод са, че можем да променяме състоянието на зависимостите, когато пожелаем, което прави този метод много гъвкав. Недостатъците са, че ако не сетнем пропъртито, то ще остане със стойност null, и съответната инстанция на клас няма да бъде валидна.
  • През параметър на метод Ако зависимостта се ползва само в текущия метод, този начин е подходящ, но ако методите са повече е добре зависимостта да се подаде чрез конструктора. Недостатъка е, че когато подаваме много параметри на метода, чупим неговата сигнатура.

Класически нарушения на принципа

  • Използване на ключовата дума „new“. Когато създавате нови инстанции на класовете, които са ви нужни, а не ги приемате както в посочените горе случаи, вие се обвързвате максимално с класовете, а не с техните абстракции (интерфейси, абстрактни класове).
  • Използване на статични класове. Статичния клас не може да има абстракция над себе си (интерфейс), което означава, че не може да имате обръщане на зависимостите и статичен клас на едно място.

Заключение

В тази статия ви бяха представени петте принципа на SOLID Code. Проекти, които се придържат към принципите на SOLID, могат да бъдат споделяни със сътрудници, разширени, модифицирани, тествани и рефакторирани с по-малко усложнения.

Използвани източници:
https://www.digitalocean.com
https://www.wikipedia.com

Вашият коментар