摘要:服務(wù)本省作為一個高層類,對外提供訪問,卻受制于提供具體服務(wù)的服務(wù)提供者定義的實現(xiàn),高層模塊依賴底層模塊實現(xiàn),違背了依賴倒置原則。遵循依賴倒置原則的例子場景同介紹中場景。
1. 名詞介紹
2. 組成部分OOD,面向?qū)ο笤O(shè)計
DIP,依賴倒置(軟件設(shè)計原則)
IOC,控制反轉(zhuǎn)(軟件設(shè)計模式)
DI,依賴注入
IOC Container,控制反轉(zhuǎn)容器,也是依賴注入容器
2. 依賴倒置原則(DIP) 2.0 介紹服務(wù)清單(功能清單,service list)
服務(wù)(高層類,service ,對外提供服務(wù))
服務(wù)提供者(底層類,service provider ,實際提供服務(wù)的對象)
依賴倒置原則,它轉(zhuǎn)換了依賴,高層模塊不依賴于低層模塊的實現(xiàn),而低層模塊依賴于高層模塊定義的接口
詳細(xì)介紹請點我
2.1 場景描述提供一個計算機(jī)儲存的服務(wù)。需要根據(jù)不同的用戶需求,使用不同的存儲設(shè)備。
2.2 沒有遵循依賴倒置原則的例子 2.2.1 定義好服務(wù)提供者(實際提供服務(wù))// 定義一個 硬盤存儲類 (服務(wù)提供者) class HardDiskStorage { public function saveToHardDisk(){ } public function readFromHardDisk(){ } } // 定義一個 U盤存儲類(服務(wù)提供者) class UStorage { public function saveToU(){ } public function readFromU(){ } }2.2.2 定義 服務(wù)(對外提供服務(wù)的對象)
/** * 定義一個 ComputerStorage 類(存儲服務(wù)) */ // 第一種:使用硬盤作為提供實際服務(wù)的對象 class ComputerStorage { protected $_storage = null; function __construct(){ $this->_storage = new HardDiskStorage(); } public function save(){ $this->_storage->saveToHardDisk(); } public function read(){ $this->_storage->readFromHardDisk(); } } // 第二種:使用 U 盤作為提供實際服務(wù)的對象 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 代碼分析
根據(jù)上面的代碼,當(dāng)切換服務(wù)提供者時,服務(wù)類的代碼需要做較多的改動。服務(wù)(ComputerStorage)本省作為一個高層類,對外提供訪問,卻受制于提供具體服務(wù)的服務(wù)提供者(HardDiskStorage、UStorage)定義的實現(xiàn)(saveToHardDisk、saveToU、readFromHardDisk、readFromU),高層模塊依賴底層模塊實現(xiàn),違背了依賴倒置原則。
2.3 遵循依賴倒置原則的例子 2.3.1 場景同 2.1 介紹中場景。
2.3.2 定義服務(wù)清單(高層模塊定義接口)interface ServiceList { public function save(); public function read(); }2.3.3 定義服務(wù)提供者
// 硬盤 class HardDiskStorage implements ServiceList { public function save(){ } public function read(){ } } // U 盤 class UStorage implements ServiceList { public function save(){ } public function read(){ } }2.3.4 定義服務(wù)
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 代碼分析
上述代碼中,事先定義了好了服務(wù)清單(接口,ServiceList),然后服務(wù)提供者實現(xiàn)這些接口(HardDiskStorage、UStorage),服務(wù)(ComputerStorage)只需要切換服務(wù)提供者即可(HardDiskStorage、UStorage),完全無需理會他們的實現(xiàn)(readFromHardDisk、readFromU...等)。高層模塊不依賴于底層模塊定義的實現(xiàn),遵循了依賴倒置原則
3. 控制反轉(zhuǎn)(IOC) + 依賴注入(DI) 3.0 介紹控制反轉(zhuǎn)(IoC),它為相互依賴的組件提供抽象,將依賴(低層模塊)對象的獲得交給第三方(系統(tǒng))來控制,即依賴對象不在被依賴模塊的類中直接通過new來獲取
詳細(xì)介紹請點我
3.1 場景同 2 場景
3.2 沒有實現(xiàn)控制反轉(zhuǎn)的例子2 中的例子就是沒有實現(xiàn)控制反轉(zhuǎn)的例子。2 中 ComputerStorage 獲取依賴(HardDiskStorage 或 UStorage)的途徑都是在 contruct 構(gòu)造函數(shù)中獲取的,即 類內(nèi)部實例化依賴獲取。
3.3 實現(xiàn)控制反轉(zhuǎn)的例子以下代碼是根據(jù) 2 中的代碼做了些許的調(diào)整。
class ComputerStorage { protected $_storage = null; /** * 內(nèi)部只獲取依賴的實例 */ 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; } // 獲取注冊表對應(yīng)類的實例 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();
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/25788.html
摘要:構(gòu)造器注入實現(xiàn)特定參數(shù)的構(gòu)造函數(shù),在新建對象時傳入所依賴類型的對象。 基本概念 1.依賴倒置(反轉(zhuǎn))原則(DIP):一種軟件架構(gòu)設(shè)計的原則(抽象概念,是一種思想)在面向?qū)ο缶幊填I(lǐng)域中,依賴反轉(zhuǎn)原則(Dependency inversion principle,DIP)是指一種特定的解耦(傳統(tǒng)的依賴關(guān)系創(chuàng)建在高層次上,而具體的策略設(shè)置則應(yīng)用在低層次的模塊上)形式,使得高層次的模塊不依賴于...
摘要:依賴注入控制反轉(zhuǎn)的一種具體實現(xiàn)方法。接下來,我們使用依賴注入實現(xiàn)控制反轉(zhuǎn),使依賴關(guān)系倒置依賴被動傳入。從單元測試的角度看,依賴注入更方便和操作,方便了測試人員寫出質(zhì)量更高的測試代碼。 前言 好的設(shè)計會提高程序的可復(fù)用性和可維護(hù)性,也間接的提高了開發(fā)人員的生產(chǎn)力。今天,我們就來說一下在很多框架中都使用的依賴注入。 一些概念 要搞清楚什么是依賴注入如何依賴注入,首先我們要明確一些概念。 D...
摘要:在中使用解耦,有兩種注入方式構(gòu)造函數(shù)注入屬性注入。對象的實例化解析依賴信息該方法實質(zhì)上就是通過的反射機(jī)制,通過類的構(gòu)造函數(shù)的參數(shù)分析他所依賴的單元。 有關(guān)概念 依賴倒置原則(Dependence Inversion Principle, DIP) 傳統(tǒng)軟件設(shè)計中,上層代碼依賴于下層代碼,當(dāng)下層出現(xiàn)變動時,上層也要相應(yīng)變化。 DIP的核心思想是:上層定義接口,下層實現(xiàn)這個接口,從而使的下...
摘要:可以為服務(wù)提供者的方法設(shè)置類型提示。方法將在所有其他服務(wù)提供者均已注冊之后調(diào)用。所有服務(wù)提供者都在配置文件中注冊??梢赃x擇推遲服務(wù)提供者的注冊,直到真正需要注冊綁定時,這樣可以提供應(yīng)用程序的性能。 本文最早發(fā)布于 Rootrl的Blog 導(dǎo)言 Laravel是一款先進(jìn)的現(xiàn)代化框架,里面有一些概念非常重要。在上手Laravel之前,我認(rèn)為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP...
摘要:前言最近在使用框架,看了下他的源碼,發(fā)現(xiàn)有很多地方也用到了依賴注入控制反轉(zhuǎn),覺得有必要和大家簡單聊一聊什么是依賴注入以及怎么使用它。概念依賴注入和控制反轉(zhuǎn)是對同一件事情的不同描述,從某個方面講,就是它們描述的角度不同。 前言 最近在使用ThinkPHP5框架,看了下他的源碼,發(fā)現(xiàn)有很多地方也用到了依賴注入(控制反轉(zhuǎn)),覺得有必要和大家簡單聊一聊什么是依賴注入以及怎么使用它。 簡介 I...
閱讀 1033·2019-08-30 15:55
閱讀 3477·2019-08-30 13:10
閱讀 1299·2019-08-29 18:45
閱讀 2384·2019-08-29 16:25
閱讀 2145·2019-08-29 15:13
閱讀 2459·2019-08-29 11:29
閱讀 581·2019-08-26 17:34
閱讀 1523·2019-08-26 13:57