OOD,面向對象設計html
DIP,依賴倒置(軟件設計原則)設計模式
IOC,控制反轉(軟件設計模式)ide
DI,依賴注入函數
IOC Container,控制反轉容器,也是依賴注入容器測試
服務清單(功能清單,service list)this
服務(高層類,service ,對外提供服務)設計
服務提供者(底層類,service provider ,實際提供服務的對象)code
依賴倒置原則,它轉換了依賴,高層模塊不依賴於低層模塊的實現,而低層模塊依賴於高層模塊定義的接口htm
詳細介紹請點我對象
提供一個計算機儲存的服務。須要根據不一樣的用戶需求,使用不一樣的存儲設備。
// 定義一個 硬盤存儲類 (服務提供者) class HardDiskStorage { public function saveToHardDisk(){ } public function readFromHardDisk(){ } } // 定義一個 U盤存儲類(服務提供者) class UStorage { public function saveToU(){ } public function readFromU(){ } }
/** * 定義一個 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();
根據上面的代碼,當切換服務提供者時,服務類的代碼須要作較多的改動。服務(ComputerStorage
)本省做爲一個高層類,對外提供訪問,卻受制於提供具體服務的服務提供者(HardDiskStorage
、UStorage
)定義的實現(saveToHardDisk
、saveToU
、readFromHardDisk
、readFromU
),高層模塊依賴底層模塊實現,違背了依賴倒置原則。
同 2.1
介紹中場景。
interface ServiceList { public function save(); public function read(); }
// 硬盤 class HardDiskStorage implements ServiceList { public function save(){ } public function read(){ } } // U 盤 class UStorage implements ServiceList { public function save(){ } public function read(){ } }
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();
上述代碼中,事先定義了好了服務清單(接口,ServiceList
),而後服務提供者實現這些接口(HardDiskStorage
、UStorage
),服務(ComputerStorage
)只須要切換服務提供者便可(HardDiskStorage
、UStorage
),徹底無需理會他們的實現(readFromHardDisk
、readFromU
...等)。高層模塊不依賴於底層模塊定義的實現,遵循了依賴倒置原則
控制反轉(IoC),它爲相互依賴的組件提供抽象,將依賴(低層模塊)對象的得到交給第三方(系統)來控制,即依賴對象不在被依賴模塊的類中直接經過new來獲取
同 2
場景
2
中的例子就是沒有實現控制反轉的例子。2
中 ComputerStorage
獲取依賴(HardDiskStorage
或 UStorage
)的途徑都是在 contruct
構造函數中獲取的,即 類內部實例化依賴獲取。
如下代碼是根據 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);
同 2
場景。
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();