日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

25外观模式(Facade Pattern)

發(fā)布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 25外观模式(Facade Pattern) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

動機(Motivate):
????在軟件開發(fā)系統(tǒng)中,客戶程序經(jīng)常會與復(fù)雜系統(tǒng)的內(nèi)部子系統(tǒng)之間產(chǎn)生耦合,而導(dǎo)致客戶程序隨著子系統(tǒng)的變化而變化。那么如何簡化客戶程序與子系統(tǒng)之間的交互接口?如何將復(fù)雜系統(tǒng)的內(nèi)部子系統(tǒng)與客戶程序之間的依賴解耦?
意圖(Intent):
????
為子系統(tǒng)中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統(tǒng)更加容易使用。
??? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? --------《設(shè)計模式》GOF
結(jié)構(gòu)圖(Struct):
??? ?? ?? ?? ???
??? ?? ?? ?? ???
?? ?? ?? ???
適用性:

??? 1.為一個復(fù)雜子系統(tǒng)提供一個簡單接口。

??? 2.提高子系統(tǒng)的獨立性。

??? 3.在層次化結(jié)構(gòu)中,可以使用Facade模式定義系統(tǒng)中每一層的入口。
生活中的例子:
????????????????
代碼實現(xiàn):
????
我們平時的開發(fā)中其實已經(jīng)不知不覺的在用Fa?ade模式,現(xiàn)在來考慮這樣一個抵押系統(tǒng),當(dāng)有一個客戶來時,有如下幾件事情需要確認:到銀行子系統(tǒng)查詢他是否有足夠多的存款,到信用子系統(tǒng)查詢他是否有良好的信用,到貸款子系統(tǒng)查詢他有無貸款劣跡。只有這三個子系統(tǒng)都通過時才可進行抵押。我們先不考慮Fa?ade模式,那么客戶程序就要直接訪問這些子系統(tǒng),分別進行判斷。類結(jié)構(gòu)圖下:?
? ? ? ? ? ? ? ???
????

在這個程序中,我們首先要有一個顧客類,它是一個純數(shù)據(jù)類,并無任何操作,示意代碼:

?1?//顧客類
?2?public?class?Customer
?3?{
?4?????private?string?_name;
?5?
?6?????public?Customer(string?name)
?7?????{
?8?????????this._name?=?name;
?9?????}
10?
11?????public?string?Name
12?????{
13?????????get?{?return?_name;?}
14?????}
15?}


下面這三個類均是子系統(tǒng)類,示意代碼:

?1?//銀行子系統(tǒng)
?2?public?class?Bank
?3?{
?4?????public?bool?HasSufficientSavings(Customer?c,?int?amount)
?5?????{
?6?????????Console.WriteLine("Check?bank?for?"?+?c.Name);
?7?????????return?true;
?8?????}
?9?}
10?
11?//信用子系統(tǒng)
12?public?class?Credit
13?{
14?????public?bool?HasGoodCredit(Customer?c)
15?????{
16?????????Console.WriteLine("Check?credit?for?"?+?c.Name);
17?????????return?true;
18?????}
19?}
20?
21?//貸款子系統(tǒng)
22?public?class?Loan
23?{
24?????public?bool?HasNoBadLoans(Customer?c)
25?????{
26?????????Console.WriteLine("Check?loans?for?"?+?c.Name);
27?????????return?true;
28?????}
29?}


看客戶程序的調(diào)用:

?1?//客戶程序
?2?public?class?MainApp
?3?{
?4?????private?const?int?_amount?=?12000;
?5?
?6?????public?static?void?Main()
?7?????{
?8?????????Bank?bank?=?new?Bank();
?9?????????Loan?loan?=?new?Loan();
10?????????Credit?credit?=?new?Credit();
11?
12?????????Customer?customer?=?new?Customer("Ann?McKinsey");
13?
14?????????bool?eligible?=?true;
15?
16?????????if?(!bank.HasSufficientSavings(customer,?_amount))
17?????????{
18?????????????eligible?=?false;
19?????????}
20?????????else?if?(!loan.HasNoBadLoans(customer))
21?????????{
22?????????????eligible?=?false;
23?????????}
24?????????else?if?(!credit.HasGoodCredit(customer))
25?????????{
26?????????????eligible?=?false;
27?????????}
28?
29?????????Console.WriteLine("\n"?+?customer.Name?+?"?has?been?"?+?(eligible???"Approved"?:?"Rejected"));
30?????????Console.ReadLine();
31?????}
32?}


可以看到,在不用Fa?ade模式的情況下,客戶程序與三個子系統(tǒng)都發(fā)生了耦合,這種耦合使得客戶程序依賴于子系統(tǒng),當(dāng)子系統(tǒng)化時,客戶程序也將面臨很多變化的挑戰(zhàn)。一個合情合理的設(shè)計就是為這些子系統(tǒng)創(chuàng)建一個統(tǒng)一的接口,這個接口簡化了客戶程序的判斷操作。看一下引入Fa?ade模式后的類結(jié)構(gòu)圖:
???????????變

外觀類Mortage的實現(xiàn)如下:

?1?/外觀類
?2?public?class?Mortgage
?3?{
?4?????private?Bank?bank?=?new?Bank();
?5?????private?Loan?loan?=?new?Loan();
?6?????private?Credit?credit?=?new?Credit();
?7?
?8?????public?bool?IsEligible(Customer?cust,?int?amount)
?9?????{
10?????????Console.WriteLine("{0}?applies?for?{1:C}?loan\n",
11???????????cust.Name,?amount);
12?
13?????????bool?eligible?=?true;
14?
15?????????if?(!bank.HasSufficientSavings(cust,?amount))
16?????????{
17?????????????eligible?=?false;
18?????????}
19?????????else?if?(!loan.HasNoBadLoans(cust))
20?????????{
21?????????????eligible?=?false;
22?????????}
23?????????else?if?(!credit.HasGoodCredit(cust))
24?????????{
25?????????????eligible?=?false;
26?????????}
27?
28?????????return?eligible;
29?????}
30?}

顧客類和子系統(tǒng)類的實現(xiàn)仍然如下:

?1?//銀行子系統(tǒng)
?2?public?class?Bank
?3?{
?4?????public?bool?HasSufficientSavings(Customer?c,?int?amount)
?5?????{
?6?????????Console.WriteLine("Check?bank?for?"?+?c.Name);
?7?????????return?true;
?8?????}
?9?}
10?
11?//信用證子系統(tǒng)
12?public?class?Credit
13?{
14?????public?bool?HasGoodCredit(Customer?c)
15?????{
16?????????Console.WriteLine("Check?credit?for?"?+?c.Name);
17?????????return?true;
18?????}
19?}
20?
21?//貸款子系統(tǒng)
22?public?class?Loan
23?{
24?????public?bool?HasNoBadLoans(Customer?c)
25?????{
26?????????Console.WriteLine("Check?loans?for?"?+?c.Name);
27?????????return?true;
28?????}
29?}
30?
31?//顧客類
32?public?class?Customer
33?{
34?????private?string?name;
35?
36?????public?Customer(string?name)
37?????{
38?????????this.name?=?name;
39?????}
40?
41?????public?string?Name
42?????{
43?????????get?{?return?name;?}
44?????}
45?}

而此時客戶程序的實現(xiàn):

?1?//客戶程序類
?2?public?class?MainApp
?3?{
?4?????public?static?void?Main()
?5?????{
?6?????????//外觀
?7?????????Mortgage?mortgage?=?new?Mortgage();
?8?
?9?????????Customer?customer?=?new?Customer("Ann?McKinsey");
10?????????bool?eligable?=?mortgage.IsEligible(customer,?125000);
11?
12?????????Console.WriteLine("\n"?+?customer.Name?+
13?????????????"?has?been?"?+?(eligable???"Approved"?:?"Rejected"));?
14?????????Console.ReadLine();
15?????}
16?}

可以看到引入Fa?ade模式后,客戶程序只與Mortgage發(fā)生依賴,也就是Mortgage屏蔽了子系統(tǒng)之間的復(fù)雜的操作,達到了解耦內(nèi)部子系統(tǒng)與客戶程序之間的依賴。
?

.NET架構(gòu)中的Fa?ade模式

Fa?ade模式在實際開發(fā)中最多的運用當(dāng)屬開發(fā)N層架構(gòu)的應(yīng)用程序了,一個典型的N層結(jié)構(gòu)如下:

???????????????

?

??? 在這個架構(gòu)中,總共分為四個邏輯層,分別為:用戶層UI,業(yè)務(wù)外觀層Business Fa?ade,業(yè)務(wù)規(guī)則層Business Rule,數(shù)據(jù)訪問層Data Access。其中Business Fa?ade層的職責(zé)如下:

l?????????從“用戶”層接收用戶輸入

l?????????如果請求需要對數(shù)據(jù)進行只讀訪問,則可能使用“數(shù)據(jù)訪問”層

l?????????將請求傳遞到“業(yè)務(wù)規(guī)則”層

l?????????將響應(yīng)從“業(yè)務(wù)規(guī)則”層返回到“用戶”層

l?????????在對“業(yè)務(wù)規(guī)則”層的調(diào)用之間維護臨時狀態(tài)

對這一架構(gòu)最好的體現(xiàn)就是Duwamish示 例了。在該應(yīng)用程序中,有部分操作只是簡單的從數(shù)據(jù)庫根據(jù)條件提取數(shù)據(jù),不需要經(jīng)過任何處理,而直接將數(shù)據(jù)顯示到網(wǎng)頁上,比如查詢某類別的圖書列表。而另 外一些操作,比如計算定單中圖書的總價并根據(jù)顧客的級別計算回扣等等,這部分往往有許多不同的功能的類,操作起來也比較復(fù)雜。如果采用傳統(tǒng)的三層結(jié)構(gòu),這 些商業(yè)邏輯一般是會放在中間層,那么對內(nèi)部的這些大量種類繁多,使用方法也各異的不同的類的調(diào)用任務(wù),就完全落到了表示層。這樣勢必會增加表示層的代碼 量,將表示層的任務(wù)復(fù)雜化,和表示層只負責(zé)接受用戶的輸入并返回結(jié)果的任務(wù)不太相稱,并增加了層與層之間的耦合程度。于是就引入了一個Fa?ade層,讓這個Facade來負責(zé)管理系統(tǒng)內(nèi)部類的調(diào)用,并為表示層提供了一個單一而簡單的接口。看一下Duwamish結(jié)構(gòu)圖:???????? ???????????????????????????????????????????????????????????????

從圖中可以看到,UI層將請求發(fā)送給業(yè)務(wù)外觀層,業(yè)務(wù)外觀層對請求進行初步的處理,判斷是否需要調(diào)用業(yè)務(wù)規(guī)則層,還是直接調(diào)用數(shù)據(jù)訪問層獲取數(shù)據(jù)。最后由數(shù)據(jù)訪問層訪問數(shù)據(jù)庫并按照來時的步驟返回結(jié)果到UI層,來看具體的代碼實現(xiàn)。

在獲取商品目錄的時候,Web UI調(diào)用業(yè)務(wù)外觀層:

1?productSystem?=?new?ProductSystem();
2?categorySet???=?productSystem.GetCategories(categoryID);


業(yè)務(wù)外觀層直接調(diào)用了數(shù)據(jù)訪問層:

?1?public?CategoryData?GetCategories(int?categoryId)
?2?{
?3?????//
?4?????//?Check?preconditions
?5?????//
?6?????ApplicationAssert.CheckCondition(categoryId?>=?0,"Invalid?Category?Id",ApplicationAssert.LineNumber);
?7?????//
?8?????//?Retrieve?the?data
?9?????//
10?????using?(Categories?accessCategories?=?new?Categories())
11?????{
12?????????return?accessCategories.GetCategories(categoryId);
13?????}
14?????
15?}


在添加訂單時,UI調(diào)用業(yè)務(wù)外觀層:

1?public?void?AddOrder()
2?{
3?????ApplicationAssert.CheckCondition(cartOrderData?!=?null,?"Order?requires?data",?ApplicationAssert.LineNumber);
4?
5?????//Write?trace?log.
6?????ApplicationLog.WriteTrace("Duwamish7.Web.Cart.AddOrder:\r\nCustomerId:?"?+
7?????????????????????????????????cartOrderData.Tables[OrderData.CUSTOMER_TABLE].Rows[0][OrderData.PKID_FIELD].ToString());
8?????cartOrderData?=?(new?OrderSystem()).AddOrder(cartOrderData);
9?}


業(yè)務(wù)外觀層調(diào)用業(yè)務(wù)規(guī)則層:

?1?public?OrderData?AddOrder(OrderData?order)
?2?{
?3?????//
?4?????//?Check?preconditions
?5?????//
?6?????ApplicationAssert.CheckCondition(order?!=?null,?"Order?is?required",?ApplicationAssert.LineNumber);
?7?????
?8?????(new?BusinessRules.Order()).InsertOrder(order);
?9?????return?order;
10?}

?

?

業(yè)務(wù)規(guī)則層進行復(fù)雜的邏輯處理后,再調(diào)用數(shù)據(jù)訪問層:

?1?public?OrderData?AddOrder(OrderData?order)
?2?{
?3?????//
?4?????//?Check?preconditions
?5?????//
?6?????ApplicationAssert.CheckCondition(order?!=?null,?"Order?is?required",?ApplicationAssert.LineNumber);
?7?????
?8?????(new?BusinessRules.Order()).InsertOrder(order);
?9?????return?order;
10?}
11?
12?
13?業(yè)務(wù)規(guī)則層進行復(fù)雜的邏輯處理后,再調(diào)用數(shù)據(jù)訪問層:
14?public?bool?InsertOrder(OrderData?order)
15?{????
16?????//
17?????//?Assume?it's?good
18?????//
19?????bool?isValid?=?true;
20?????//????????????
21?????//?Validate?order?summary
22?????//
23?????DataRow?summaryRow?=?order.Tables[OrderData.ORDER_SUMMARY_TABLE].Rows[0];
24?????
25?????summaryRow.ClearErrors();
26?
27?????if?(CalculateShipping(order)?!=?(Decimal)(summaryRow[OrderData.SHIPPING_HANDLING_FIELD]))
28?????{
29?????????summaryRow.SetColumnError(OrderData.SHIPPING_HANDLING_FIELD,?OrderData.INVALID_FIELD);
30?????????isValid?=?false;
31?????}
32?
33?????if?(CalculateTax(order)?!=?(Decimal)(summaryRow[OrderData.TAX_FIELD]))
34?????{
35?????????summaryRow.SetColumnError(OrderData.TAX_FIELD,?OrderData.INVALID_FIELD);
36?????????isValid?=?false;
37?????}
38?????//????
39?????//?Validate?shipping?info
40?????//
41?????isValid?&=?IsValidField(order,?OrderData.SHIPPING_ADDRESS_TABLE,?OrderData.SHIP_TO_NAME_FIELD,?40);
42?????//
43?????//?Validate?payment?info?
44?????//
45?????DataRow?paymentRow?=?order.Tables[OrderData.PAYMENT_TABLE].Rows[0];
46?????
47?????paymentRow.ClearErrors();
48?????
49?????isValid?&=?IsValidField(paymentRow,?OrderData.CREDIT_CARD_TYPE_FIELD,?40);
50?????isValid?&=?IsValidField(paymentRow,?OrderData.CREDIT_CARD_NUMBER_FIELD,??32);
51?????isValid?&=?IsValidField(paymentRow,?OrderData.EXPIRATION_DATE_FIELD,?30);
52?????isValid?&=?IsValidField(paymentRow,?OrderData.NAME_ON_CARD_FIELD,?40);
53?????isValid?&=?IsValidField(paymentRow,?OrderData.BILLING_ADDRESS_FIELD,?255);
54?????//
55?????//?Validate?the?order?items?and?recalculate?the?subtotal
56?????//
57?????DataRowCollection?itemRows?=?order.Tables[OrderData.ORDER_ITEMS_TABLE].Rows;
58?????
59?????Decimal?subTotal?=?0;
60?????
61?????foreach?(DataRow?itemRow?in?itemRows)
62?????{
63?????????itemRow.ClearErrors();
64?????????
65?????????subTotal?+=?(Decimal)(itemRow[OrderData.EXTENDED_FIELD]);
66?????????
67?????????if?((Decimal)(itemRow[OrderData.PRICE_FIELD])?<=?0)
68?????????{
69?????????????itemRow.SetColumnError(OrderData.PRICE_FIELD,?OrderData.INVALID_FIELD);
70?????????????isValid?=?false;
71?????????}
72?
73?????????if?((short)(itemRow[OrderData.QUANTITY_FIELD])?<=?0)
74?????????{
75?????????????itemRow.SetColumnError(OrderData.QUANTITY_FIELD,?OrderData.INVALID_FIELD);
76?????????????isValid?=?false;
77?????????}
78?????}
79?????//
80?????//?Verify?the?subtotal
81?????//
82?????if?(subTotal?!=?(Decimal)(summaryRow[OrderData.SUB_TOTAL_FIELD]))
83?????{
84?????????summaryRow.SetColumnError(OrderData.SUB_TOTAL_FIELD,?OrderData.INVALID_FIELD);
85?????????isValid?=?false;
86?????}
87?
88?????if?(?isValid?)
89?????{
90?????????using?(DataAccess.Orders?ordersDataAccess?=?new?DataAccess.Orders())
91?????????{
92?????????????return?(ordersDataAccess.InsertOrderDetail(order))?>?0;
93?????????}
94?????}
95?????else
96?????????return?false;
97?}


Facade模式的個要點:
??? 從客戶程序的角度來看,Facade模式不僅簡化了整個組件系統(tǒng)的接口,同時對于組件內(nèi)部與外部客戶程序來說,從某種程度上也達到了一種“解耦”的效果----內(nèi)部子系統(tǒng)的任何變化不會影響到Facade接口的變化。

??? Facade設(shè)計模式更注重從架構(gòu)的層次去看整個系統(tǒng),而不是單個類的層次。Facdae很多時候更是一種架構(gòu)
設(shè)計模式。
??? 注意區(qū)分Facade模式、Adapter模式、Bridge模式與Decorator模式。Facade模式注重簡化接口,Adapter模式注重轉(zhuǎn)換接口,Bridge模式注重分離接口(抽象)與其實現(xiàn),Decorator模式注重穩(wěn)定接口的前提下為對象擴展功能。

總結(jié)

以上是生活随笔為你收集整理的25外观模式(Facade Pattern)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。