概述 在軟件開發系統中,客戶程序會與很復雜系統的內部子系統之間產生耦合,而導致客戶程序隨著子系統的變化而變化,那麼如何簡化客戶程序與子系統之間的交互接口?如何將復雜系統的內部子系統與客戶程序之間的依賴解耦?這就需要我們的外觀模式再好不過了。 目的 為子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。 結構圖 對應源碼 [csharp] <span style="font-size:18px;"> class Program { static void Main(string[] args) { Facade facade = new Facade(); //由於Facade的作用,客戶端可以根本不知三個子系統類的存在, facade.MethodA(); facade.MethodB(); Console.Read(); } } //四個子系統的類 class SubSystemOne { public void MethodOne() { Console.WriteLine(" 子系統方法一"); } } class SubSystemTwo { public void MethodTwo() { Console.WriteLine(" 子系統方法二"); } } class SubSystemThree { public void MethodThree() { Console.WriteLine(" 子系統方法三"); } } class SubSystemFour { public void MethodFour() { Console.WriteLine(" 子系統方法四"); } } //外觀類 class Facade { SubSystemOne one; SubSystemTwo two; SubSystemThree three; SubSystemFour four; //外觀類,它需要了解所有的子系統的方法或屬性鏡像組合,已被外界調用 public Facade() { one = new SubSystemOne(); two = new SubSystemTwo(); three = new SubSystemThree(); four = new SubSystemFour(); } public void MethodA() { Console.WriteLine("\n方法組A() ---- "); one.MethodOne(); two.MethodTwo(); four.MethodFour(); } public void MethodB() { Console.WriteLine("\n方法組B() ---- "); two.MethodTwo(); three.MethodThree(); } }</span> 運行結果 使用外觀模式時機 (1):在設計初期階段,應該要有意識的將不同的兩個層分離,例如:三層結構,需要在數據訪問層、業務邏輯層、表示層的層層之間建立外觀模式,可以是復雜的子系統提供一個簡單的接口,使得耦合度大大降低 (2):在開發階段,子系統由於不斷的重構演化而變得越來越復雜,增加外觀模式可以提供一個簡單的接口,減少它們之間的依賴 (3):在維護一個遺留的大型系統時,可能這個系統已經很難以維護和擴展了,但是它有很重要的功能,新的需求依賴它,使用外觀模式也是非常合適的。 (4):外觀模式,它不限制它們使用子系統類,可以再系統易用性和通用性之間選擇。 (5):Facade模式對客戶屏蔽了子系統組件,減少了客戶處理的對象的數目使得子系統使用起來更加方便。 生活實例 現在來說快遞行業很是火,我們很多人想由物件到制定的地方,我們要到快遞機構填寫我們要去的地址,之後,快遞公司會根據我們不同的郵寄地址而准確的分開,此時快遞的前台機構就是扮演著這個“外觀”,他負責協調客戶的訂單、發送地點等工作他起到了一個接口的工作。 經典實例(投資基金) [csharp] <span style="font-size:18px;"> class Program { static void Main(string[] args) { Fund jijin = new Fund(); jijin.BuyFund(); jijin.SellFund(); Console.Read(); } } class Fund { Stock1 gu1; Stock2 gu2; Stock3 gu3; NationalDebt1 nd1; Realty1 rt1; //基金類,外觀模式點,進行組合,已被外界調用 public Fund() { gu1 = new Stock1(); gu2 = new Stock2(); gu3 = new Stock3(); nd1 = new NationalDebt1(); rt1 = new Realty1(); } public void BuyFund() { gu1.Buy(); gu2.Buy(); gu3.Buy(); nd1.Buy(); rt1.Buy(); } public void SellFund() { gu1.Sell(); gu2.Sell(); gu3.Sell(); nd1.Sell(); rt1.Sell(); } } //股票1 class Stock1 { //賣股票 public void Sell() { Console.WriteLine(" 股票1賣出"); } //買股票 public void Buy() { Console.WriteLine(" 股票1買入"); } } //股票2 class Stock2 { //賣股票 public void Sell() { Console.WriteLine(" 股票2賣出"); } //買股票 public void Buy() { Console.WriteLine(" 股票2買入"); } } //股票3 class Stock3 { //賣股票 public void Sell() { Console.WriteLine(" 股票3賣出"); } //買股票 public void Buy() { Console.WriteLine(" 股票3買入"); } } //國債1 class NationalDebt1 { //賣國債 public void Sell() { Console.WriteLine(" 國債1賣出"); } //買國債 public void Buy() { Console.WriteLine(" 國債1買入"); } } //房地產1 class Realty1 { //賣房地產 public void Sell() { Console.WriteLine(" 房產1賣出"); } //買房地產 public void Buy() { Console.WriteLine(" 房產1買入"); } }</span> 運行結果 總結 外觀模式作為結構型模式中的一個簡單又實用的模式,外觀模式通過封裝細節來提供大粒度的調用,直接的好處就是,封裝細節,提供了應用寫程序的可維護性和易用性。外觀模式一般應用在系統架構的服務層中,當我們是多個不同類型的客戶端應用程序時,比如一個系統既可以在通過Web的形式訪問,也可以通過客戶端應用程序的形式時,可能通過外觀模式來提供遠程服務,讓應用程序進行遠程調用,這樣通過外觀形式提供服務,那麼不管是什麼樣的客戶端都訪問一致的外觀服務,那麼以後就算是我們的應用服務發生變化,那麼我們不需要修改沒一個客戶端應用的調用,只需要修改相應的外觀應用即可,從某種程度上也達到了一種“解耦”的效果. Facade設計模式更注重從架構的層次去看整個系統,而不是單個類的層次。Facdae很多時候更是一種架構 設計模式。 重要的區分:Facade模式、Adapter模式、Bridge模式與Decorator模式。Facade模式注重簡化接口,Adapter模式注重轉換接口,Bridge模式注重分離接口(抽象)與其實現,Decorator模式注重穩定接口的前提下為對象擴展功能。