PHP: SOLID [D] Zasada odwracania zależności
Przyszedł czas na opisanie ostatniej zasady SOLID. Oczywiście jest to literka „D”, zasada w oryginalnej nazwie brzmi:
„Dependency Inversion Principle” co tłumaczymy na „Zasada odwracania zależności„.
Wstęp
Treść zasady brzmi następująco:
„Wysokopoziomowe moduły nie powinny zależeć od modułów niskopoziomowych – zależności między nimi powinny wynikać z abstrakcji.„
Najlepiej od razu przejść do przykładu na którym najprościej zrozumieć zasadę odwracania zależności.
Praktyka
Posłużmy się przykładem inicjowania płatności w naszym systemie.
Klasę inicjującą płatność Pay() można nazwać kodem wysokopoziomowym
class Pay { public $name = 'PayPal'; private $payment; public function __construct(Interfaces\Pay $pay) { $this->payment = $pay; } public function implement() : string { return 'Implementuję płatność: ' . $this->payment->implement(); } }
Kod wysokopoziomowy nie powinien zależeć od kodu niskopoziomowego, czyli PayU() oraz PayPal()
class PayPal implements Interfaces\Pay { private $name = 'PayPal'; public function __construct() { //kod konstruktora } public function implement() : string { return $this->name; } }
class PayU implements Interfaces\Pay { private $name = 'PayU'; public function __construct() { //kod konstruktora } public function implement() : string { return $this->name; } }
Zależność pomiędzy kodem niskopoziomowym a wysokopoziomowym, powinna wynikać z ich abstrakcji.
Dla nas abstrakcją jest interfejs Pay:
interface Pay { public function implement(); }
Kod sterujący (kontroler):
$methodPay = new Controller\PayPal(); $pay = new Controller\Pay($methodPay);
Do klasy „Pay()” wstrzykujemy zależność („Dependency Injection„), klasa ta spodziewa się obiektu korzystającego z interfejsu „Pay„, ale nie wie jaki rodzaj płatności inicjuje.
Klasie „Pay” tak na prawdę wystarczy wiedza taka, że obiekt jaki otrzymuje korzysta z interfejsu płatności „Pay„, ale wiedza dotycząca konkretnego rodzaju jest już zbędna.
Podsumowanie
Odwrócenie sterowania („IoC„) zostało na powyższym przykładzie rozwiązane za pomocą wstrzyknięcia zależności („DI„). Jest to jednak tylko jedna z możliwości, można bowiem napisać kod zgodny z wzorcem odwrócenia sterowania innymi metodami (wikipedia).