本筆記摘抄自:https://www.cnblogs.com/PatrickLiu/p/7772184.html,記錄一下學習過程以備後續查用。 一、引言 今天我們要講結構型設計模式的第五個模式--外觀模式。先從名字上來理解一下外觀模式,當看到“外觀”這個詞時,很容易想到“外表”這個詞語,兩者有著 ...
本筆記摘抄自:https://www.cnblogs.com/PatrickLiu/p/7772184.html,記錄一下學習過程以備後續查用。
一、引言
今天我們要講結構型設計模式的第五個模式--外觀模式。先從名字上來理解一下外觀模式,當看到“外觀”這個詞時,很容易想到“外表”這個詞語,兩者有著
很相近的意思。就拿談戀愛來說,“外表”很重要,如果第一眼看著很舒服、有眼緣,那就有交往下去的可能。如果長得“三寸釘、枯樹皮”,估計就夠嗆了。
在這方面,“外觀”和“外表”有著相同的作用。在軟體系統中,要完成一個功能如果需要調用很多介面,不僅增加了開發及調試難度,也增加了維護的複雜度。
如果把這些介面再封裝一次,給一個很好的“外觀”,讓使用者只需調用一個介面,就可以完成以前調用多個介面來完成的任務,這樣使用起來就方便多了。
這個模式很簡單,大家很容易理解,可能大家在編碼的過程中已經不止一次使用過該模式了,只是不知道名字罷了。現實生活中這樣的例子很多,舉不勝
舉,來一幅圖,大家看看就明白了。
二、外觀模式介紹
外觀模式:英文名稱--Facade Pattern;分類--結構型。
2.1、動機(Motivate)
在軟體系統開發的過程中,當組件的客戶(即外部介面或客戶程式)和組件中各種複雜的子系統有了過多的耦合,隨著外部客戶程式和各子系統的演化,這
種過多的耦合面臨很多變化的挑戰。如何簡化外部客戶程式和系統間的交互介面?如何將外部客戶程式的演化和內部子系統的變化之間的依賴相互解耦?
2.2、意圖(Intent)
為子系統中的一組介面提供一個一致的界面,Facade模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。——《設計模式》GoF
2.3、結構圖(Structure)
2.4、模式的組成
外觀模式包含如下兩個角色:
1)外觀角色(Facade):在客戶端可以調用它的方法,在外觀角色中可以知道相關的(一個或者多個)子系統的功能和責任;在正常情況下,它將所有從
客戶端發來的請求委派到相應的子系統去,傳遞給相應的子系統對象處理。
2)子系統角色(SubSystem):在軟體系統中可以有一個或者多個子系統角色,每一個子系統可以不是一個單獨的類,而是一個類的集合,它實現子系統
的功能;每一個子系統都可以被客戶端直接調用,或者被外觀角色調用,它處理由外觀類傳過來的請求;子系統並不知道外觀的存在,對於子系統而言,外觀
角色僅僅是另外一個客戶端而已。
2.5、外觀模式的具體實現
馬上就到“雙11”了,人們又開始瘋狂地購買了。其實購買的過程很複雜,但是我們在購買的過程只需要選擇自己喜歡的商品,也可以加入購物車,最後點擊
付款就完成了。其實這個過程沒有那麼簡單,下麵就模仿一下購買的過程吧。
購買過程有幾點必須要做的事情:
1)身份認證,如果沒有認證就是無效用戶。
2)系統安全,檢查系統環境,防止註入、跨站和偽造等攻擊。
3)網銀安全,檢查付款地址的有效性,檢查網關是否正常。
class Program { /// <summary> /// 身份認證子系統A /// </summary> public class AuthoriationSystemA { public void MethodA() { Console.WriteLine("執行身份認證。"); } } /// <summary> /// 系統安全子系統B /// </summary> public class SecuritySystemB { public void MethodB() { Console.WriteLine("執行系統安全檢查。"); } } /// <summary> /// 網銀安全子系統C /// </summary> public class NetBankSystemC { public void MethodC() { Console.WriteLine("執行網銀安全檢測。"); } } /// <summary> /// 更高層的Facade /// </summary> public class SystemFacade { private AuthoriationSystemA auth; private SecuritySystemB security; private NetBankSystemC netbank; public SystemFacade() { auth = new AuthoriationSystemA(); security = new SecuritySystemB(); netbank = new NetBankSystemC(); } public void Buy() { auth.MethodA(); //身份認證子系統 security.MethodB(); //系統安全子系統 netbank.MethodC(); //網銀安全子系統 Console.WriteLine("我已經成功購買了。"); } } static void Main(string[] args) { #region 外觀模式 SystemFacade facade = new SystemFacade(); facade.Buy(); Console.Read(); #endregion } }View Code
運行結果如下:
這個模式很簡單,就話不多說了。
三、外觀模式的實現要點
1)一個系統可以有幾個外觀類
在外觀模式中,通常只需要一個外觀類並且此外觀類只有一個實例,換言之它是一個單例類。當然這並不意味著在整個系統里只有一個外觀類,而僅僅是說
對每一個子系統只有一個外觀類。或者說,如果一個系統有好幾個子系統的話,每一個子系統都有一個外觀類,整個系統可以有數個外觀類。
2)為子系統增加新行為
初學者往往以為通過繼承一個外觀類便可在子系統中加入新的行為,這是錯誤的。外觀模式的用意是為子系統提供一個集中化和簡化的溝通管道,而不能向
子系統加入新的行為。比如醫院中的接待員並不是醫護人員,接待員並不能為病人提供醫療服務。
3)Facade有助於建立層次結構的系統,實現了子系統與客戶之間的松耦合關係,子系統內部的功能組件往往是緊耦合的。松耦合關係使得子系統的組件變
化不會影響到它的客戶。Facade消除了複雜的迴圈依賴關係,這一點在客戶程式與子系統分別實現的時候格外重要。
4)從客戶程式的角度來看,Facade模式不僅簡化了整個組件系統的介面,同時對於組件內部與外部客戶程式來說,從某種程度上也達到了一種“解耦”的效
果,因為內部子系統的任何變化不會影響到Facade介面的變化。
3.1、外觀模式的優點
1)外觀模式對客戶屏蔽了子系統組件,從而簡化了介面,減少了客戶處理的對象數目並使子系統的使用更加簡單。
2)外觀模式實現了子系統與客戶之間的松耦合關係,而子系統內部的功能組件是緊耦合的。松耦合使得子系統的組件變化不會影響到它的客戶。
3.2、外觀模式的缺點
1)如果增加新的子系統可能需要修改外觀類或客戶端的源代碼,這樣就違背了”開閉原則“(不過這點也是不可避免)。
3.3、在以下情況下可以考慮使用外觀模式
1)為一個複雜的子系統提供一個簡單的介面。
2)提供子系統的獨立性。
3)在層次化結構中,可以使用外觀模式定義系統中每一層的入口,其中三層架構就是這樣的一個例子。
四、.NET 中外觀模式的實現
外觀模式在FCL裡面的運用還是很多的,多數情況是單個類的情況。在Asp.Net裡面,有很多複合控制項,比如:Login控制項,可以登錄、認證、保存登錄用戶
信息。其實,外觀模式更多的是應用在業務系統當中,效果更好。
五、總結
這個模式很簡單,就不說了,就稍微做一下小結。Facade設計模式更註重從架構的層次去看整個系統,而不是單個類的層次。Facade很多時候更是一種架
構設計模式。註意區分Facade模式、Adapter模式、Bridge模式與Decorator模式:
Facade模式註重簡化介面
Adapter模式註重轉換介面
Bridge模式註重分離介面(抽象)與其實現
Decorator模式註重穩定介面的前提下為對象擴展功能