注意
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);

 







arrow
arrow
    全站熱搜

    wbkuo 發表在 痞客邦 留言(0) 人氣()