.Net結(jié)構(gòu)型設(shè)計模式之外觀模式(Facade)
一、動機(Motivate)
在軟件系統(tǒng)開發(fā)的過程中,當(dāng)組件的客戶(即外部接口,或客戶程序)和組件中各種復(fù)雜的子系統(tǒng)有了過多的耦合,隨著外部客戶程序和各子系統(tǒng)的演化,這種過多的耦合面臨很多變化的挑戰(zhàn)。如何簡化外部客戶程序和系統(tǒng)間的交互接口?如何將外部客戶程序的演化和內(nèi)部子系統(tǒng)的變化之間的依賴相互解耦?
二、意圖(Intent)
為子系統(tǒng)中的一組接口提供一個一致的界面,F(xiàn)acade模式定義了一個高層接口,這個接口使得這一子系統(tǒng)更加容易使用?! ?mdash;—《設(shè)計模式》GoF
三、結(jié)構(gòu)圖(Structure)
四、模式的組成
外觀模式包含如下兩個角色:
(1)、外觀角色(Facade):在客戶端可以調(diào)用它的方法,在外觀角色中可以知道相關(guān)的(一個或者多個)子系統(tǒng)的功能和責(zé)任;在正常情況下,它將所有從客戶端發(fā)來的請求委派到相應(yīng)的子系統(tǒng)去,傳遞給相應(yīng)的子系統(tǒng)對象處理。
(2)、子系統(tǒng)角色(SubSystem):在軟件系統(tǒng)中可以有一個或者多個子系統(tǒng)角色,每一個子系統(tǒng)可以不是一個單獨的類,而是一個類的集合,它實現(xiàn)子系統(tǒng)的功能;每一個子系統(tǒng)都可以被客戶端直接調(diào)用,或者被外觀角色調(diào)用,它處理由外觀類傳過來的請求;子系統(tǒng)并不知道外觀的存在,對于子系統(tǒng)而言,外觀角色僅僅是另外一個客戶端而已。
五、外觀模式的具體實現(xiàn)
購物的過程很復(fù)雜,但是我們在購買的過程只需要選擇自己喜歡的商品,也可以加入購物車,最后點擊付款就完成了。其實這個過程沒有那么簡單。我們下面就模仿一下購買的過程吧。
購買過程有幾點必須要做的事情:
1、身份驗證安全,沒有認(rèn)證是無效用戶。
2、系統(tǒng)安全,檢查系統(tǒng)環(huán)境,防止注入、跨站和偽造等攻擊
3、網(wǎng)銀安全,檢查付款地址的有效性,檢查網(wǎng)關(guān)是否正常
/// <summary> /// 不使用外觀模式的情況 /// 此時客戶端與三個子系統(tǒng)都發(fā)送了耦合,使得客戶端程序依賴與子系統(tǒng) /// 為了解決這樣的問題,我們可以使用外觀模式來為所有子系統(tǒng)設(shè)計一個統(tǒng)一的接口 /// 客戶端只需要調(diào)用外觀類中的方法就可以了,簡化了客戶端的操作 /// 從而讓客戶和子系統(tǒng)之間避免了緊耦合 /// </summary> static void Main(string[] args) { SystemFacade facade = new SystemFacade(); facade.Buy();//用戶點擊購買就完成了。 } // 身份認(rèn)證子系統(tǒng)A public class AuthoriationSystemA { public void MethodA() { Console.WriteLine("執(zhí)行身份認(rèn)證"); } } // 系統(tǒng)安全子系統(tǒng)B public class SecuritySystemB { public void MethodB() { Console.WriteLine("執(zhí)行系統(tǒng)安全檢查"); } } // 網(wǎng)銀安全子系統(tǒng)C public class NetBankSystemC { public void MethodC() { Console.WriteLine("執(zhí)行網(wǎng)銀安全檢測"); } } //更高層的Facade 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();//身份認(rèn)證子系統(tǒng) security.MethodB();//系統(tǒng)安全子系統(tǒng) netbank.MethodC();//網(wǎng)銀安全子系統(tǒng) Console.WriteLine("我已經(jīng)成功購買了!"); } }
六、實現(xiàn)要點:
1、一個系統(tǒng)可以有幾個門面類
在門面模式中,通常只需要一個門面類,并且此門面類只有一個實例,換言之它是一個單例類。當(dāng)然這并不意味著在整個系統(tǒng)里只有一個門面類,而僅僅是說對每一個子系統(tǒng)只有一個門面類?;蛘哒f,如果一個系統(tǒng)有好幾個子系統(tǒng)的話,每一個子系統(tǒng)都有一個門面類,整個系統(tǒng)可以有數(shù)個門面類。
2、為子系統(tǒng)增加新行為
初學(xué)者往往以為通過繼承一個門面類便可在子系統(tǒng)中加入新的行為,這是錯誤的。門面模式的用意是為子系統(tǒng)提供一個集中化和簡化的溝通管道,而不能向子系統(tǒng)加入新的行為。比如醫(yī)院中的接待員并不是醫(yī)護人員,接待員并不能為病人提供醫(yī)療服務(wù)。
3、Facade有助于建立層次結(jié)構(gòu)的系統(tǒng),實現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系,子系統(tǒng)內(nèi)部的功能組件往往是緊耦合的。松耦合關(guān)系使得子系統(tǒng)的組件變化不會影響到它的客戶。Facade消除了復(fù)雜的循環(huán)依賴關(guān)系。這一點在客戶程序與子系統(tǒng)分別實現(xiàn)的時候格外重要。
4、從客戶程序的角度來看,F(xiàn)acade模式不僅簡化了整個組件系統(tǒng)的接口,同時對于組件內(nèi)部與外部客戶程序來說,從某種程度上也達到了一種“解耦”的效果——內(nèi)部子系統(tǒng)的任何變化不會影響到Facade接口的變化。
1、外觀模式的優(yōu)點:
(1)、外觀模式對客戶屏蔽了子系統(tǒng)組件,從而簡化了接口,減少了客戶處理的對象數(shù)目并使子系統(tǒng)的使用更加簡單。
(2)、外觀模式實現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系,而子系統(tǒng)內(nèi)部的功能組件是緊耦合的。松耦合使得子系統(tǒng)的組件變化不會影響到它的客戶。
2、外觀模式的缺點:
如果增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼,這樣就違背了”開——閉原則“(不過這點也是不可避免)。
3、在以下情況下可以考慮使用外觀模式:
(1)、外一個復(fù)雜的子系統(tǒng)提供一個簡單的接口
(2)、提供子系統(tǒng)的獨立性
(3)、在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口。其中三層架構(gòu)就是這樣的一個例子。
七.NET 中外觀模式的實現(xiàn)
外觀模式在FCL里面運用還是很多的,多數(shù)情況是單個類的情況,在Asp.Net里面,有很多復(fù)合控件,比如:Login控件,可以登錄,可以認(rèn)證,可以保存登錄用戶信息。其實,外觀模式更多的是應(yīng)用在業(yè)務(wù)系統(tǒng)當(dāng)中,效果更好。
到此這篇關(guān)于.Net結(jié)構(gòu)型設(shè)計模式之外觀模式(Facade)的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
那些年,我還在學(xué)asp.net(一) 學(xué)習(xí)筆記
那些年到此,基本學(xué)習(xí)了前端的基本知識,那些年的第四課就是asp.net,當(dāng)然那時看了很多教程,比如說:天轟穿,當(dāng)然天轟穿說得比較多,如面向?qū)ο螅珻#知識,由于當(dāng)時上過C++,所以就沒有看這些,直接從asp.net開始,主要是學(xué)習(xí)一下asp.net用到的一些基本控件2012-03-03.Net行為型設(shè)計模式之迭代器模式(Iterator)
這篇文章介紹了.Net行為型設(shè)計模式之迭代器模式(Iterator),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05ASP.NET?Core托管模型CreateDefaultBuilder()方法
這篇文章介紹了ASP.NET?Core托管模型CreateDefaultBuilder()方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02.NET?Core使用flyfire.CustomSerialPort實現(xiàn)Windows/Linux跨平臺串口通訊
本文詳細(xì)講解了.NET?Core使用flyfire.CustomSerialPort實現(xiàn)Windows/Linux跨平臺串口通訊的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-01-01ASP.NET?Core中的Configuration配置一
這篇文章介紹了ASP.NET?Core中的Configuration配置,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04ASP.NET MVC中_ViewStart.cshtml作用介紹
這篇文章介紹了ASP.NET MVC中_ViewStart.cshtml的作用,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03創(chuàng)建ASP.NET?Core?Web應(yīng)用程序并介紹項目模板
這篇文章介紹了創(chuàng)建ASP.NET?Core?Web應(yīng)用程序的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02