注意
1. 這篇只是個人的筆記,不保證正確,如需正確版本請多 Google 幾篇 Dependency Injection 的文章來看。
2. 如有錯誤,歡迎指正,我會非常感謝!
參考網址
1. Huan-Lin 學習筆記 - Dependency Injection 筆記 (1)
2. 網站製作學習誌 - 理解 Dependency Injection 實作原理
3. Injection Patterns
4. Wiki - Dependency injection
概念
相依性注入(Dependency Injection) 的意思,就是在類別中原本相依於另一類別的部份,將其定義成可由建構子傳入或是執行時傳入
透過統一的介面(Interface)或抽象類別來限制傳入的部份要符合的規範,以達到執行執行隨時切換相依性的類別的方法。
簡單來說:就是不在類別中使用特定的其他類別,而是當成參數傳入到該類別之中。
範例
1. 不使用 DI 的寫法
<?php // 車子的父類別 abstract class Car_base { abstract public function run(); } // 車子的子類別 class car extends Car_base { public function run() { echo "Drive a Car...<br>"; } } class People { public function drive() { $car = new Car(); $car->run(); } } // 使用 People 類別 $leo = new People(); $leo->drive();
如要改騎機車(類別 Motocycle),則程式要修改成以下樣子
<?php // 車子的父類別 abstract class Car_base { abstract public function run(); } // 車子的子類別 class car extends Car_base { public function run() { echo "Drive a Car...<br>"; } } // 機車的子類別 class Motocycle extends Car_base { public function run() { echo "Riding a Motocycle...<br>"; } } class People { public function drive() { $car = new Motocycle(); $car->run(); } } // 使用 People 類別 $leo = new People(); $leo->drive();
2. 使用相依性注入(Dependency Injection) 的寫法
一般來說相依性注入實作方式有三種類型(感謝師兄提供):
1. Constructor Injection:從建構子注入
2. Property Injection:使用 setter method 帶入
3. Method Injection:執行時帶入
* Constructor Injection: 由建構子傳入
<?php // 車子的父類別 abstract class Car_base { abstract public function run(); } // 車子的子類別 class car extends Car_base { public function run() { echo "Drive a Car...<br>"; } } // 機車的子類別 class Motocycle extends Car_base { public function run() { echo "Riding a Motocycle...<br>"; } } class People { private $car; public function __construct(Car_base $car) { $this->car = $car; } public function drive() { $this->car->run(); } } // 使用 People 類別 $rv150 = new Motocycle(); $leo = new People($rv150); $leo->drive();
註: Motocycle 改為不在 People 裡面建立,而是由建構子傳入已建立完成的實體
* Property Injection:使用 setter method 帶入
<?php // 車子的父類別 abstract class Car_base { abstract public function run(); } // 車子的子類別 class car extends Car_base { public function run() { echo "Drive a Car...<br>"; } } // 機車的子類別 class Motocycle extends Car_base { public function run() { echo "Riding a Motocycle...<br>"; } } class People { private $car; public function set_car(Car_base $car) { $this->car = $car; } public function drive() { $this->car->run(); } } // 使用 People 類別 $rv150 = new Motocycle(); $leo = new People(); $leo->set_car($rv150); $leo->drive();
* Method Injection:執行時傳入
<?php // 車子的父類別 abstract class Car_base { abstract public function run(); } // 車子的子類別 class car extends Car_base { public function run() { echo "Drive a Car...<br>"; } } // 機車的子類別 class Motocycle extends Car_base { public function run() { echo "Riding a Motocycle...<br>"; } } class People { public function drive(Car_base $car) { $car->run(); } } // 使用 People 類別 $rv150 = new Motocycle(); $vios = new Car(); $leo = new People(); $leo->drive($rv150); $leo->drive($vios);
留言列表