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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

10.外观模式(Facade Pattern)

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

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

?

?


適用性:

??? 1.為一個復雜子系統提供一個簡單接口。

??? 2.提高子系統的獨立性。

??? 3.在層次化結構中,可以使用Facade模式定義系統中每一層的入口。
生活中的例子:


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


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

?

//顧客類

public class Customer{private string _name;public Customer(string name){this._name = name;}public string Name{get { return _name; }}}

?


下面這三個類均是子系統類,示意代碼:

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

?


//信用子系統public class Credit{public bool HasGoodCredit(Customer c){Console.WriteLine("Check credit for " + c.Name);return true;}}

?


//貸款子系統public class Loan{public bool HasNoBadLoans(Customer c){Console.WriteLine("Check loans for " + c.Name);return true;}} }

?


看客戶程序的調用:

//客戶程序
class Program{private const int _amount = 12000;static void Main(string[] args){Bank bank = new Bank();Credit credit = new Credit();Loan loan = new Loan();Customer customer = new Customer("Ann McKinsey");bool eligible = true;if (!bank.HasSufficientSavings(customer, _amount)){eligible = false;}else if (!credit.HasGoodCredit(customer)){eligible = false;}else if (!loan.HasNoBadLoans(customer)){eligible = false;}Console.WriteLine("\n" + customer.Name + " has been " + (eligible ? "Approved" : "Rejected"));Console.ReadLine();}}

?


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

?

?

顧客類和子系統類的實現仍然如下:

//銀行子系統public class Bank{public bool HasSufficientSavings(Customer c, int amount){Console.WriteLine("Check bank for " + c.Name);return true;}}//信用子系統public class Credit{public bool HasGoodCredit(Customer c){Console.WriteLine("Check credit for " + c.Name);return true;}}//貸款子系統public class Loan{public bool HasNoBadLoans(Customer c){Console.WriteLine("Check loans for " + c.Name);return true;}}

?


//顧客類public class Customer{private string _name;public Customer(string name){this._name = name;}public string Name{get { return _name; }}}

?


外觀類Mortage的實現如下:

/// <summary>/// 外觀類/// </summary>public class Mortgage{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;}}

?

而此時客戶程序的實現:

//客戶程序類
class Program{private const int _amount = 12000;static void Main(string[] args){//外觀Mortgage mortgage = new Mortgage();Customer customer = new Customer("Ann McKinsey");bool eligable = mortgage.IsEligible(customer, _amount);Console.WriteLine("\n" + customer.Name + " has been " + (eligable ? "Approved" : "Rejected"));Console.ReadLine(); }}

?

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

.NET架構中的Facade模式

Facade模式在實際開發中最多的運用當屬開發N層架的應用程序了,一個典型的N層結構如下:

?

在這個架構中,總共分為四個邏輯層,分別為:用戶層UI,業務外觀層Business Facade,業務規則層Business Rule,數據訪問層Data Access。其中Business Facade層的職責如下:

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

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

l?????????將請求傳遞到“業務規則”層

l?????????將響應從“業務規則”層返回到“用戶”層

l?????????在對“業務規則”層的調用之間維護臨時狀態

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

?

從圖中可以看到,UI層將請求發送給業務外觀層,業務外觀層對請求進行初步的處理,判斷是否需要調用業務規則層,還是直接調用數據訪問層獲取數據。最后由數據訪問層訪問數據庫并按照來時的步驟返回結果到UI層,來看具體的代碼實現。

在獲取商品目錄的時候,Web UI調用業務外觀層:

productSystem = new ProductSystem();categorySet = productSystem.GetCategories(categoryID);

?


業務外觀層直接調用了數據訪問層:

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

?


在添加訂單時,UI調用業務外觀層:

public void AddOrder(){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);}

?


業務外觀層調用業務規則層:

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

?

?

業務規則層進行復雜的邏輯處理后,再調用數據訪問層:

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

?

業務規則層進行復雜的邏輯處理后,再調用數據訪問層:
public bool InsertOrder(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;}}elsereturn false;}}

?

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

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

轉載于:https://www.cnblogs.com/1285026182YUAN/p/5162752.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。