OOD、DIP、IOC、DI、依賴注入容器(即 控制反轉容器,IOC Container)

1. 名詞介紹

  1. OOD,面向對象設計html

  2. DIP,依賴倒置(軟件設計原則)設計模式

  3. IOC,控制反轉(軟件設計模式)ide

  4. DI,依賴注入函數

  5. IOC Container,控制反轉容器,也是依賴注入容器測試

2. 組成部分

  1. 服務清單(功能清單,service list)this

  2. 服務(高層類,service ,對外提供服務)設計

  3. 服務提供者(底層類,service provider ,實際提供服務的對象)code

2. 依賴倒置原則(DIP)

2.0 介紹

依賴倒置原則,它轉換了依賴,高層模塊不依賴於低層模塊的實現,而低層模塊依賴於高層模塊定義的接口htm

詳細介紹請點我對象

2.1 場景描述

提供一個計算機儲存的服務。須要根據不一樣的用戶需求,使用不一樣的存儲設備。

2.2 沒有遵循依賴倒置原則的例子

2.2.1 定義好服務提供者(實際提供服務)

// 定義一個 硬盤存儲類 (服務提供者)
class HardDiskStorage {
    public function saveToHardDisk(){
        
    }
    
    public function readFromHardDisk(){
        
    }
}

// 定義一個 U盤存儲類(服務提供者)
class UStorage {
    public function saveToU(){
        
    }
    
    public function readFromU(){
        
    }
}

2.2.2 定義 服務(對外提供服務的對象)

/**
 * 定義一個 ComputerStorage 類(存儲服務)
 */ 

// 第一種:使用硬盤做爲提供實際服務的對象
class ComputerStorage {
    protected $_storage = null;
    
    function __construct(){
        $this->_storage = new HardDiskStorage();
    }
    
    public function save(){
        $this->_storage->saveToHardDisk();
    }
    
    public function read(){
        $this->_storage->readFromHardDisk();
    }
}

// 第二種:使用 U 盤做爲提供實際服務的對象
class ComputerStorage {
    protected $_storage = null;
    
    function __construct(){
        $this->_storage = new UStorage();
    }
    
    public function save(){
        $this->_storage->saveToU();
    }
    
    public function read(){
        $this->_storage->readFromU();
    }
}

// 讀取
$cs = new ComputerStorage();
$cs->read();

2.2.3 代碼分析

根據上面的代碼,當切換服務提供者時,服務類的代碼須要作較多的改動。服務(ComputerStorage)本省做爲一個高層類,對外提供訪問,卻受制於提供具體服務的服務提供者(HardDiskStorageUStorage)定義的實現(saveToHardDisksaveToUreadFromHardDiskreadFromU),高層模塊依賴底層模塊實現,違背了依賴倒置原則。

2.3 遵循依賴倒置原則的例子

2.3.1 場景

2.1 介紹中場景。

2.3.2 定義服務清單(高層模塊定義接口)

interface ServiceList {
    public function save();
    public function read();
}

2.3.3 定義服務提供者

// 硬盤
class HardDiskStorage implements ServiceList {
    public function save(){
        
    }
    
    public function read(){
        
    }
}

// U 盤
class UStorage implements ServiceList {
    public function save(){
        
    }
    
    public function read(){
        
    }
}

2.3.4 定義服務

class ComputerStorage {
    protected $_storage = null;
    
    function __construct(){
        $this->_storage = new HardDiskStorage();        
    }
    
    public function save(){
        $this->_storage->save();
    }
    
    public function read(){
        $this->_storage->read();
    }
}

$cs = new ComputerStorage();
$cs->read();

2.3.5 代碼分析

上述代碼中,事先定義了好了服務清單(接口,ServiceList),而後服務提供者實現這些接口(HardDiskStorageUStorage),服務(ComputerStorage)只須要切換服務提供者便可(HardDiskStorageUStorage),徹底無需理會他們的實現(readFromHardDiskreadFromU...等)。高層模塊不依賴於底層模塊定義的實現,遵循了依賴倒置原則

3. 控制反轉(IOC) + 依賴注入(DI)

3.0 介紹

控制反轉(IoC),它爲相互依賴的組件提供抽象,將依賴(低層模塊)對象的得到交給第三方(系統)來控制,即依賴對象不在被依賴模塊的類中直接經過new來獲取

詳細介紹請點我

3.1 場景

2 場景

3.2 沒有實現控制反轉的例子

2 中的例子就是沒有實現控制反轉的例子。2ComputerStorage 獲取依賴(HardDiskStorageUStorage)的途徑都是在 contruct 構造函數中獲取的,即 類內部實例化依賴獲取。

3.3 實現控制反轉的例子

如下代碼是根據 2 中的代碼作了些許的調整。

class ComputerStorage {
    protected $_storage = null;
    
    /**
     * 內部只獲取依賴的實例
     */
    public function setStorage($storage){
        $this->_storage = $storage;
    }

    public function save(){
        $this->_storage->save();
    }
    
    public function read(){
        $this->_storage->read();
    }
}

// 外部實例化依賴
$hardDiskStorage = new HardDiskStorage();

$cs = new ComputerStorage();
// 注入依賴
$cs->setStorage($hardDiskStorage);

4. 依賴注入容器(IOC 容器)

4.0 場景

2 場景。

4.1 使用 IOC容器

class Container {
    // 註冊表
    protected static $_registry = null;
    
    // 保存到註冊表
    public static function set($classname , Callable $create){
        self::$_registry[$classname] = $create;
    }
    
    // 獲取註冊表對應類的實例
    public static function get($key){
        call_user_func(self::$_registry[$key]);
    }
}

class ComputerStorage {
    protected $_storage = null;
    
    function __construct(){
        $this->_storage = Container::get('HardDiskStorage');
    }
    
    public function read(){
        $this->_storage->read();
    }
    
    public function save(){
        $this->_storage->save();
    }
}

/**
 * 註冊依賴
 */
Container::set('HardDiskStorage' , function(){
    return new HardDiskStorage();
});

Container::set('UStorage' , function(){
    return new UStorage();
});

// 測試
$cs = new ComputerStorage();

$cs->read();
相關文章
相關標籤/搜索