您好,登錄后才能下訂單哦!
這篇文章主要講解了“講解PHP設(shè)計模式外觀模式Facade-結(jié)構(gòu)型”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“講解PHP設(shè)計模式外觀模式Facade-結(jié)構(gòu)型”吧!
外觀模式,我們通過外觀的包裝,使應(yīng)用程序只能看到外觀對象,而不會看到具體的細節(jié)對象,這樣無疑會降低應(yīng)用程序的復(fù)雜度,并且提高了程序的可維護性。
例子1:一個電源總開關(guān)可以控制四盞燈、一個風(fēng)扇、一臺空調(diào)和一臺電視機的啟動和關(guān)閉。該電源總開關(guān)可以同時控制上述所有電器設(shè)備,電源總開關(guān)即為該系統(tǒng)的外觀模式設(shè)計。
為了降低復(fù)雜性,常常將系統(tǒng)劃分為若干個子系統(tǒng)。但是如何做到各個系統(tǒng)之間的通信和相互依賴關(guān)系達到最小呢?
外觀模式:為子系統(tǒng)中的一組接口提供一個一致的界面, Facade模式定義了一個高層接口,這個接口使得這一子系統(tǒng)更加容易使用。引入外觀角色之后,用戶只需要直接與外觀角色交互,用戶與子系統(tǒng)之間的復(fù)雜關(guān)系由外觀角色來實現(xiàn),從而降低了系統(tǒng)的耦合度。
在遇到以下情況使用facade模式:
1) 當你要為一個復(fù)雜子系統(tǒng)提供一個簡單接口時。子系統(tǒng)往往因為不斷演化而變得越來越復(fù)雜。大多數(shù)模式使用時都會產(chǎn)生更多更小的類。
這使得子系統(tǒng)更具可重用性,也更容易對子系統(tǒng)進行定制,但這也給那些不需要定制子系統(tǒng)的用戶帶來一些使用上的困難。facade可以提供一個簡單的缺省視圖,
這一視圖對大多數(shù)用戶來說已經(jīng)足夠,而那些需要更多的可定制性的用戶可以越過facade層。
2) 客戶程序與抽象類的實現(xiàn)部分之間存在著很大的依賴性。引入 facade將這個子系統(tǒng)與客戶以及其他的子系統(tǒng)分離,可以提高子系統(tǒng)的獨立性 和可移植性。
3) 當你需要構(gòu)建一個層次結(jié)構(gòu)的子系統(tǒng)時,使用 facade模式定義子系統(tǒng)中每層的入口點。如果子系統(tǒng)之間是相互依賴的,你可以讓它們僅通過facade進行通訊,從而簡化了它們之間的依賴關(guān)系。
外觀角色(Facade):是模式的核心,他被客戶client角色調(diào)用,知道各個子系統(tǒng)的功能。同時根據(jù)客戶角色已有的需求預(yù)訂了幾種功能組合\
子系統(tǒng)角色(Subsystem classes):實現(xiàn)子系統(tǒng)的功能,并處理由Facade對象指派的任務(wù)。對子系統(tǒng)而言,facade和client角色是未知的,沒有Facade的任何相關(guān)信息;即沒有指向Facade的實例。
客戶角色(client):調(diào)用facade角色獲得完成相應(yīng)的功能。
Facade模式有下面一些優(yōu)點:
1)對客戶屏蔽子系統(tǒng)組件,減少了客戶處理的對象數(shù)目并使得子系統(tǒng)使用起來更加容易。通過引入外觀模式,客戶代碼將變得很簡單,與之關(guān)聯(lián)的對象也很少。
2)實現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系,這使得子系統(tǒng)的組件變化不會影響到調(diào)用它的客戶類,只需要調(diào)整外觀類即可。
3)降低了大型軟件系統(tǒng)中的編譯依賴性,并簡化了系統(tǒng)在不同平臺之間的移植過程,因為編譯一個子系統(tǒng)一般不需要編譯所有其他的子系統(tǒng)。一個子系統(tǒng)的修改對其他子系統(tǒng)沒有任何影響,而且子系統(tǒng)內(nèi)部變化也不會影響到外觀對象。
4)只是提供了一個訪問子系統(tǒng)的統(tǒng)一入口,并不影響用戶直接使用子系統(tǒng)類。
Facade模式的缺點
1) 不能很好地限制客戶使用子系統(tǒng)類,如果對客戶訪問子系統(tǒng)類做太多的限制則減少了可變性和靈活性。
2) 在不引入抽象外觀類的情況下,增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼,違背了“開閉原則”。
我們使用開關(guān)的例子;
<?php /** * 外觀模式 * */ class SwitchFacade { private $_light = null; //電燈 private $_ac = null; //空調(diào) private $_fan = null; //電扇 private $_tv = null; //電視 public function __construct() { $this->_light = new Light(); $this->_fan = new Fan(); $this->_ac = new AirConditioner(); $this->_tv = new Television(); } /** * 晚上開電燈 * */ public function method1($isOpen =1) { if ($isOpen == 1) { $this->_light->on(); $this->_fan->on(); $this->_ac->on(); $this->_tv->on(); }else{ $this->_light->off(); $this->_fan->off(); $this->_ac->off(); $this->_tv->off(); } } /** * 白天不需要電燈 * */ public function method2() { if ($isOpen == 1) { $this->_fan->on(); $this->_ac->on(); $this->_tv->on(); }else{ $this->_fan->off(); $this->_ac->off(); $this->_tv->off(); } } } /******************************************子系統(tǒng)類 ************/ /** * */ class Light { private $_isOpen = 0; public function on() { echo 'Light is open', '<br/>'; $this->_isOpen = 1; } public function off() { echo 'Light is off', '<br/>'; $this->_isOpen = 0; } } class Fan { private $_isOpen = 0; public function on() { echo 'Fan is open', '<br/>'; $this->_isOpen = 1; } public function off() { echo 'Fan is off', '<br/>'; $this->_isOpen = 0; } } class AirConditioner { private $_isOpen = 0; public function on() { echo 'AirConditioner is open', '<br/>'; $this->_isOpen = 1; } public function off() { echo 'AirConditioner is off', '<br/>'; $this->_isOpen = 0; } } class Television { private $_isOpen = 0; public function on() { echo 'Television is open', '<br/>'; $this->_isOpen = 1; } public function off() { echo 'Television is off', '<br/>'; $this->_isOpen = 0; } } /** * 客戶類 * */ class client { static function open() { $f = new SwitchFacade(); $f->method1(1); } static function close() { $f = new SwitchFacade(); $f->method1(0); } } client::open();
1)抽象工廠模式:Abstract Factory式可以與Facade模式一起使用以提供一個接口,這一接口可用來以一種子系統(tǒng)獨立的方式創(chuàng)建子系統(tǒng)對象。 Abstract Factory也可以代替Facade模式隱藏那些與平臺相關(guān)的類。
2)中介模式:Mediator模式與Facade模式的相似之處是,它抽象了一些已有的類的功能。然而,Mediator的目的是對同事之間的任意通訊進行抽象,通常集中不屬于任何單個對象的功能。
Mediator的同事對象知道中介者并與它通信,而不是直接與其他同類對象通信。相對而言,F(xiàn)acade模式僅對子系統(tǒng)對象的接口進行抽象,從而使它們更容易使用;它并不定義新功能,子系統(tǒng)也不知道Facade的存在。
通常來講,僅需要一個Facade對象,因此Facade對象通常屬于Singleton模式。
3)Adapter模式:
適配器模式是將一個接口通過適配來間接轉(zhuǎn)換為另一個接口。
外觀模式的話,其主要是提供一個整潔的一致的接口給客戶端。
1)根據(jù)“單一職責(zé)原則”,在軟件中將一個系統(tǒng)劃分為若干個子系統(tǒng)有利于降低整個系統(tǒng)的復(fù)雜性,一個常見的設(shè)計目標是使子系統(tǒng)間的通信和相互依賴關(guān)系達到最小,而達到該目標的途徑之一就是引入一個外觀對象,它為子系統(tǒng)的訪問提供了一個簡單而單一的入口。
2)外觀模式也是“迪米特法則”的體現(xiàn),通過引入一個新的外觀類可以降低原有系統(tǒng)的復(fù)雜度,外觀類充當了客戶類與子系統(tǒng)類之間的“第三者”,同時降低客戶類與子系統(tǒng)類的耦合度。外觀模式就是實現(xiàn)代碼重構(gòu)以便達到“迪米特法則”要求的一個強有力的武器。
3)外觀模式要求一個子系統(tǒng)的外部與其內(nèi)部的通信通過一個統(tǒng)一的外觀對象進行,外觀類將客戶端與子系統(tǒng)的內(nèi)部復(fù)雜性分隔開,使得客戶端只需要與外觀對象打交道,而不需要與子系統(tǒng)內(nèi)部的很多對象打交道。 4)外觀模式從很大程度上提高了客戶端使用的便捷性,使得客戶端無須關(guān)心子系統(tǒng)的工作細節(jié),通過外觀角色即可調(diào)用相關(guān)功能。 5)不要試圖通過外觀類為子系統(tǒng)增加新行為 ,不要通過繼承一個外觀類在子系統(tǒng)中加入新的行為,這種做法是錯誤的。外觀模式的用意是為子系統(tǒng)提供一個集中化和簡化的溝通渠道,而不是向子系統(tǒng)加入新的行為,新的行為的增加應(yīng)該通過修改原有子系統(tǒng)類或增加新的子系統(tǒng)類來實現(xiàn),不能通過外觀類來實現(xiàn)。
一個系統(tǒng)有多個外觀類:
在外觀模式中,通常只需要一個外觀類,并且此外觀類只有一個實例,換言之它是一個單例類。在很多情況下為了節(jié)約系統(tǒng)資源,一般將外觀類設(shè)計為單例類。當然這并不意味著在整個系統(tǒng)里只能有一個外觀類,在一個系統(tǒng)中可以設(shè)計多個外觀類,每個外觀類都負責(zé)和一些特定的子系統(tǒng)交互,向用戶提供相應(yīng)的業(yè)務(wù)功能。
不要試圖通過外觀類為子系統(tǒng)增加新行為:
不要通過繼承一個外觀類在子系統(tǒng)中加入新的行為,這種做法是錯誤的。外觀模式的用意是為子系統(tǒng)提供一個集中化和簡化的溝通渠道,而不是向子系統(tǒng)加入新的行為,新的行為的增加應(yīng)該通過修改原有子系統(tǒng)類或增加新的子系統(tǒng)類來實現(xiàn),不能通過外觀類來實現(xiàn)。
外觀模式與迪米特法則:
外觀模式創(chuàng)造出一個外觀對象,將客戶端所涉及的屬于一個子系統(tǒng)的協(xié)作伙伴的數(shù)量減到最少,使得客戶端與子系統(tǒng)內(nèi)部的對象的相互作用被外觀對象所取代。外觀類充當了客戶類與子系統(tǒng)類之間的“第三者”,降低了客戶類與子系統(tǒng)類之間的耦合度,外觀模式就是實現(xiàn)代碼重構(gòu)以便達到“迪米特法則”要求的一個強有力的武器。
抽象外觀類的引入:
外觀模式最大的缺點在于違背了“開閉原則”,當增加新的子系統(tǒng)或者移除子系統(tǒng)時需要修改外觀類,可以通過引入抽象外觀類在一定程度上解決該問題,客戶端針對抽象外觀類進行編程。對于新的業(yè)務(wù)需求,不修改原有外觀類,而對應(yīng)增加一個新的具體外觀類,由新的具體外觀類來關(guān)聯(lián)新的子系統(tǒng)對象,同時通過修改配置文件來達到不修改源代碼并更換外觀類的目的。
UML:
感謝各位的閱讀,以上就是“講解PHP設(shè)計模式外觀模式Facade-結(jié)構(gòu)型”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對講解PHP設(shè)計模式外觀模式Facade-結(jié)構(gòu)型這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。