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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

外观模式(Façade Pattern)

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

概述

在軟件開發(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)與客戶程序之間的依賴解耦?這就是要說的Fa?ade 模式。


意圖

為子系統(tǒng)中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統(tǒng)更加容易使用。[GOF 《設(shè)計模式》]

示意圖

門面模式?jīng)]有一個一般化的類圖描述,下面是一個示意性的對象圖:

圖1 Fa?ade模式示意性對象圖

生活中的例子

外觀模式為子系統(tǒng)中的接口定義了一個統(tǒng)一的更高層次的界面,以便于使用。當(dāng)消費(fèi)者按照目錄采購時,則體現(xiàn)了一個外觀模式。消費(fèi)者撥打一個號碼與客服代表聯(lián)系,客服代表則扮演了這個"外觀",他包含了與訂貨部、收銀部和送貨部的接口。

圖2使用電話訂貨例子的外觀模式對象圖

Facade模式解說

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

圖3

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

?

?

//顧客類
public?classCustomer
{
????private?string?_name;

????public?Customer(string?name)
????{
????????this._name?=?name;
????}


????public?string?Name
????{
????????get?{?return?_name;?}
????}

}


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

//銀行子系統(tǒng)
public?classBank
{
????public?bool?HasSufficientSavings(Customer?c,?int?amount)
????{
????????Console.WriteLine("Check?bank?for?"?+?c.Name);
????????return?true;
????}

}


//信用子系統(tǒng)
public?classCredit
{
????public?bool?HasGoodCredit(Customer?c)
????{
????????Console.WriteLine("Check?credit?for?"?+?c.Name);
????????return?true;
????}

}


//貸款子系統(tǒng)
public?classLoan
{
????public?bool?HasNoBadLoans(Customer?c)
????{
????????Console.WriteLine("Check?loans?for?"?+?c.Name);
????????return?true;
????}

}


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

//客戶程序
public?classMainApp
{
????private?const?int?_amount?=?12000;

????public?static?void?Main()
????{
????????Bank?bank?=?new?Bank();
????????Loan?loan?=?new?Loan();
????????Credit?credit?=?new?Credit();

????????Customer?customer?=?new?Customer("Ann?McKinsey");

????????bool?eligible?=?true;

????????if?(!bank.HasSufficientSavings(customer,?_amount))
????????{
????????????eligible?=?false;
????????}

????????else?if?(!loan.HasNoBadLoans(customer))
????????{
????????????eligible?=?false;
????????}

????????else?if?(!credit.HasGoodCredit(customer))
????????{
????????????eligible?=?false;
????????}


????????Console.WriteLine("\n"?+?customer.Name?+?"?has?been?"?+?(eligible???"Approved"?:?"Rejected"));
????????Console.ReadLine();
????}

}


可以看到,在不用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)圖:

圖4

門面類Mortage的實現(xiàn)如下:

?

//外觀類
public?classMortgage
{
????private?Bank?bank?=?new?Bank();
????private?Loan?loan?=?new?Loan();
????private?Credit?credit?=?new?Credit();

????public?bool?IsEligible(Customer?cust,?int?amount)
????{
????????Console.WriteLine("{0}?applies?for?{1:C}?loan\n",
??????????cust.Name,?amount);

????????bool?eligible?=?true;

????????if?(!bank.HasSufficientSavings(cust,?amount))
????????{
????????????eligible?=?false;
????????}

????????else?if?(!loan.HasNoBadLoans(cust))
????????{
????????????eligible?=?false;
????????}

????????else?if?(!credit.HasGoodCredit(cust))
????????{
????????????eligible?=?false;
????????}


????????return?eligible;
????}

}


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

?

//銀行子系統(tǒng)
public?classBank
{
????public?bool?HasSufficientSavings(Customer?c,?int?amount)
????{
????????Console.WriteLine("Check?bank?for?"?+?c.Name);
????????return?true;
????}
}

//信用證子系統(tǒng)
public?classCredit
{
????public?bool?HasGoodCredit(Customer?c)
????{
????????Console.WriteLine("Check?credit?for?"?+?c.Name);
????????return?true;
????}

}


//貸款子系統(tǒng)
public?classLoan
{
????public?bool?HasNoBadLoans(Customer?c)
????{
????????Console.WriteLine("Check?loans?for?"?+?c.Name);
????????return?true;
????}

}


//顧客類
public?classCustomer
{
????private?string?name;

????public?Customer(string?name)
????{
????????this.name?=?name;
????}


????public?string?Name
????{
????????get?{?return?name;?}
????}

}


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

//客戶程序類
public?classMainApp
{
????public?static?void?Main()
????{
????????//外觀
????????Mortgage?mortgage?=?new?Mortgage();

????????Customer?customer?=?new?Customer("Ann?McKinsey");
????????bool?eligable?=?mortgage.IsEligible(customer,?125000);

????????Console.WriteLine("\n"?+?customer.Name?+
????????????"?has?been?"?+?(eligable???"Approved"?:?"Rejected"));?
????????Console.ReadLine();
????}

}


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

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

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

圖5

在這個架構(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ù)進(jìn)行只讀訪問,則可能使用“數(shù)據(jù)訪問”層

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

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

l???????? 在對“業(yè)務(wù)規(guī)則”層的調(diào)用之間維護(hù)臨時狀態(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ù)雜化,和表示層只負(fù)責(zé)接受用戶的輸入并返回結(jié)果的任務(wù)不太相稱,并增加了層與層之間的耦合程度。于是就引入了一個Fa?ade層,讓這個Facade來負(fù)責(zé)管理系統(tǒng)內(nèi)部類的調(diào)用,并為表示層提供了一個單一而簡單的接口??匆幌翫uwamish結(jié)構(gòu)圖:

圖6

從圖中可以看到,UI層將請求發(fā)送給業(yè)務(wù)外觀層,業(yè)務(wù)外觀層對請求進(jìn)行初步的處理,判斷是否需要調(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ù)外觀層:

?

?

productSystem?=?newProductSystem();
categorySet???=productSystem.GetCategories(categoryID);


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

publicCategoryData?GetCategories(intcategoryId)
{
????//
????//?Check?preconditions
????//
????ApplicationAssert.CheckCondition(categoryId?>=?0,"Invalid?Category?Id",ApplicationAssert.LineNumber);
????//
????//?Retrieve?the?data
????//
????using?(Categories?accessCategories?=?new?Categories())
????{
????????return?accessCategories.GetCategories(categoryId);
????}

????
}


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

public?voidAddOrder()
{
????ApplicationAssert.CheckCondition(cartOrderData?!=?null,?"Order?requires?data",?ApplicationAssert.LineNumber);

????//Write?trace?log.
????ApplicationLog.WriteTrace("Duwamish7.Web.Cart.AddOrder:\r\nCustomerId:?"?+
????????????????????????????????cartOrderData.Tables[OrderData.CUSTOMER_TABLE].Rows[0][OrderData.PKID_FIELD].ToString());
????cartOrderData?=?(new?OrderSystem()).AddOrder(cartOrderData);
}


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

?

publicOrderData?AddOrder(OrderData?order)
{
????//
????//?Check?preconditions
????//
????ApplicationAssert.CheckCondition(order?!=?null,?"Order?is?required",?ApplicationAssert.LineNumber);
????
????(new?BusinessRules.Order()).InsertOrder(order);
????return?order;
}


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

public?boolInsertOrder(OrderData?order)
{????
????//
????//?Assume?it's?good
????//
????bool?isValid?=?true;
????//????????????
????//?Validate?order?summary
????//
????DataRow?summaryRow?=?order.Tables[OrderData.ORDER_SUMMARY_TABLE].Rows[0];
????
????summaryRow.ClearErrors();

????if?(CalculateShipping(order)?!=?(Decimal)(summaryRow[OrderData.SHIPPING_HANDLING_FIELD]))
????{
????????summaryRow.SetColumnError(OrderData.SHIPPING_HANDLING_FIELD,?OrderData.INVALID_FIELD);
????????isValid?=?false;
????}


????if?(CalculateTax(order)?!=?(Decimal)(summaryRow[OrderData.TAX_FIELD]))
????{
????????summaryRow.SetColumnError(OrderData.TAX_FIELD,?OrderData.INVALID_FIELD);
????????isValid?=?false;
????}

????//????
????//?Validate?shipping?info
????//
????isValid?&=?IsValidField(order,?OrderData.SHIPPING_ADDRESS_TABLE,?OrderData.SHIP_TO_NAME_FIELD,?40);
????//
????//?Validate?payment?info?
????//
????DataRow?paymentRow?=?order.Tables[OrderData.PAYMENT_TABLE].Rows[0];
????
????paymentRow.ClearErrors();
????
????isValid?&=?IsValidField(paymentRow,?OrderData.CREDIT_CARD_TYPE_FIELD,?40);
????isValid?&=?IsValidField(paymentRow,?OrderData.CREDIT_CARD_NUMBER_FIELD,??32);
????isValid?&=?IsValidField(paymentRow,?OrderData.EXPIRATION_DATE_FIELD,?30);
????isValid?&=?IsValidField(paymentRow,?OrderData.NAME_ON_CARD_FIELD,?40);
????isValid?&=?IsValidField(paymentRow,?OrderData.BILLING_ADDRESS_FIELD,?255);
????//
????//?Validate?the?order?items?and?recalculate?the?subtotal
????//
????DataRowCollection?itemRows?=?order.Tables[OrderData.ORDER_ITEMS_TABLE].Rows;
????
????Decimal?subTotal?=?0;
????
????foreach?(DataRow?itemRow?in?itemRows)
????{
????????itemRow.ClearErrors();
????????
????????subTotal?+=?(Decimal)(itemRow[OrderData.EXTENDED_FIELD]);
????????
????????if?((Decimal)(itemRow[OrderData.PRICE_FIELD])?<=?0)
????????{
????????????itemRow.SetColumnError(OrderData.PRICE_FIELD,?OrderData.INVALID_FIELD);
????????????isValid?=?false;
????????}


????????if?((short)(itemRow[OrderData.QUANTITY_FIELD])?<=?0)
????????{
????????????itemRow.SetColumnError(OrderData.QUANTITY_FIELD,?OrderData.INVALID_FIELD);
????????????isValid?=?false;
????????}

????}

????//
????//?Verify?the?subtotal
????//
????if?(subTotal?!=?(Decimal)(summaryRow[OrderData.SUB_TOTAL_FIELD]))
????{
????????summaryRow.SetColumnError(OrderData.SUB_TOTAL_FIELD,?OrderData.INVALID_FIELD);
????????isValid?=?false;
????}


????if?(?isValid?)
????{
????????using?(DataAccess.Orders?ordersDataAccess?=?new?DataAccess.Orders())
????????{
????????????return?(ordersDataAccess.InsertOrderDetail(order))?>?0;
????????}

????}

????else
????????return?false;
}

[MSDN]

效果及實現(xiàn)要點(diǎn)

1.Fa?ade模式對客戶屏蔽了子系統(tǒng)組件,因而減少了客戶處理的對象的數(shù)目并使得子系統(tǒng)使用起來更加方便。

2.Fa?ade模式實現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系,而子系統(tǒng)內(nèi)部的功能組件往往是緊耦合的。松耦合關(guān)系使得子系統(tǒng)的組件變化不會影響到它的客戶。

3.如果應(yīng)用需要,它并不限制它們使用子系統(tǒng)類。因此你可以在系統(tǒng)易用性與通用性之間選擇。

適用性

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

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

3.在層次化結(jié)構(gòu)中,可以使用Facade模式定義系統(tǒng)中每一層的入口。

總結(jié)

Fa?ade模式注重的是簡化接口,它更多的時候是從架構(gòu)的層次去看整個系統(tǒng),而并非單個類的層次。

轉(zhuǎn)載于:https://www.cnblogs.com/whitetiger/archive/2007/03/31/694814.html

總結(jié)

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

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

主站蜘蛛池模板: 亚洲免费网| 麻豆91精品| 色婷婷在线影院 | 香蕉视频2020| av久久久 | 国产午夜在线视频 | 久久爱综合 | 黄色中文 | 最新毛片基地 | 久久久久久影院 | 黄色一级一片免费播放 | 久久国产夫妻 | 国产一区二区中文字幕 | 欧美无马| 久久99久久99精品中文字幕 | 草草视频在线播放 | 打白嫩屁屁网站视频短裙 | 色噜噜在线播放 | 亚洲欧美国产日韩精品 | 美女福利一区 | 95视频在线 | 久久精品视频7 | 波多野结衣av在线观看 | 免费的av片 | 无码人妻一区二区三区一 | 素人av在线| www.好吊色 | 精品国产一二三 | 打美女屁股网站 | 一区二区三区欧美在线 | 青青草免费看 | 国产三级视频在线播放 | 少妇高潮一区二区三区99小说 | 狠狠97| av巨作 | 岛国大片在线免费观看 | 草草视频在线免费观看 | 中文字幕+乱码+中文字幕一区 | av女优天堂网| 黄a在线观看 | 午夜亚洲aⅴ无码高潮片苍井空 | 日本在线视频一区 | 精品国产乱码久久久久久婷婷 | 成人免费黄色片 | 国产av无码专区亚洲av毛片搜 | 国模杨依粉嫩蝴蝶150p | 亚洲欧美精品一区二区三区 | 少妇精品高潮欲妇又嫩中文字幕 | 免费毛片a | 成人网在线观看 | 精品一区二区三区四区视频 | 精品在线视频免费观看 | 久久99久久99精品 | 美女光屁屁露胸胸 | 成人av免费在线观看 | 精品久久久久久无码人妻 | 久久免费激情视频 | 亚洲啊v | 日韩精品一区在线观看 | 精品国产91久久久久久久妲己 | 极品少妇xxxx精品少妇 | 97天天干 | 日本高潮视频 | 久久综合久久88 | аⅴ资源新版在线天堂 | 成人性视频网 | 99热影院| 国产91精品一区 | 久久久噜噜噜久久中文字幕色伊伊 | 怡红院一区二区 | juliaann办公室丝袜大战 | 蜜乳av一区二区三区 | 99国产精品久久久久久久成人 | 日韩不卡免费视频 | 国产视频久久久久久久 | 国产精品嫩草69影院 | 成人免费黄色 | 国产精品免费一区二区三区在线观看 | 国产孕妇一区二区三区 | 九色国产在线 | 男人晚上看的视频 | 国产成人不卡 | 精久久久久久久 | 亚洲人成免费电影 | 久久久久久久久黄色 | 一区二区视频在线播放 | 一本色道久久hezyo加勒比 | 成人黄色av网站 | 98av视频 | 精品一区二区国产 | 激情网站免费 | 亚洲三级久久 | 波多野结衣爱爱 | 精久久久 | 亚洲伦理一区二区三区 | 双性娇喘浑圆奶水h男男漫画 | jizz免费视频 | 视频一区二区中文字幕 | 色综合免费视频 |