1. 程式人生 > 實用技巧 >結構型模式之外觀模式

結構型模式之外觀模式

目錄

在現實生活中,常常存在辦事較複雜的例子,如辦房產證或註冊一家公司,有時要同多個部門聯絡,這時要是有一個綜合部門能解決一切手續問題就好了。

軟體設計也是這樣,當一個系統的功能越來越強,子系統會越來越多,客戶對系統的訪問也變得越來越複雜。這時如果系統內部發生改變,客戶端也要跟著改變,這違背了“開閉原則”,也違背了“迪米特法則”,所以有必要為多個子系統提供一個統一的介面,從而降低系統的耦合度,這就是外觀模式的目標。

客戶去當地房產局辦理房產證過戶要遇到的相關部門:

定義與特點

外觀(Facade)模式的定義:是一種通過為多個複雜的子系統提供一個一致的介面,而使這些子系統更加容易被訪問的模式。該模式對外有一個統一介面,外部應用程式不用關心內部子系統的具體的細節,這樣會大大降低應用程式的複雜度,提高了程式的可維護性。

外觀(Facade)模式是“迪米特法則”的典型應用,它有以下主要優點:

  • 降低了子系統與客戶端之間的耦合度,使得子系統的變化不會影響呼叫它的客戶類。
  • 對客戶遮蔽了子系統元件,減少了客戶處理的物件數目,並使得子系統使用起來更加容易。
  • 降低了大型軟體系統中的編譯依賴性,簡化了系統在不同平臺之間的移植過程,因為編譯一個子系統不會影響其他的子系統,也不會影響外觀物件。

外觀(Facade)模式的主要缺點如下:

  • 不能很好地限制客戶使用子系統類。
  • 增加新的子系統可能需要修改外觀類或客戶端的原始碼,違背了“開閉原則”。

結構與實現

外觀(Facade)模式的結構比較簡單,主要是定義了一個高層介面。它包含了對各個子系統的引用,客戶端可以通過它訪問各個子系統的功能。

模式的結構

外觀(Facade)模式包含以下主要角色:

  • 外觀(Facade)角色:為多個子系統對外提供一個共同的介面。
  • 子系統(Sub System)角色:實現系統的部分功能,客戶可以通過外觀角色訪問它。
  • 客戶(Client)角色:通過一個外觀角色訪問各個子系統的功能。

其結構圖如圖所示:

模式的實現

外觀模式的實現程式碼如下:

class Program
{
    static void Main(string[] args)
    {
        Facade f = new Facade();
        f.method();
        Console.ReadLine();
    }
}

//外觀角色
public class Facade
{
    private SubSystem01 obj1=new SubSystem01();
    private SubSystem02 obj2=new SubSystem02();
    private SubSystem03 obj3=new SubSystem03();
    public void method()
    {
        obj1.Method1();
        obj2.Method2();
        obj3.Method3();
    }
}
//子系統角色
public class SubSystem01
{
    public  void Method1()
    {
        Console.WriteLine("子系統01的Method1()被呼叫!");
    }   
}

//子系統角色
public class SubSystem02
{
    public  void Method2()
    {
        Console.WriteLine("子系統02的Method2()被呼叫!");
    }   
}

//子系統角色
public class SubSystem03
{
    public  void Method3()
    {
        Console.WriteLine("子系統03的Method3()被呼叫!");
    }   
}

程式執行結果如下:

子系統01的Method1()被呼叫!
子系統02的Method2()被呼叫!
子系統03的Method3()被呼叫!

應用場景

通常在以下情況下可以考慮使用外觀模式:

  • 對分層結構系統構建時,使用外觀模式定義子系統中每層的入口點可以簡化子系統之間的依賴關係。
  • 當一個複雜系統的子系統很多時,外觀模式可以為系統設計一個簡單的介面供外界訪問。
  • 當客戶端與多個子系統之間存在很大的聯絡時,引入外觀模式可將它們分離,從而提高子系統的獨立性和可移植性。

擴充套件:引入抽象外觀類

在外觀模式中,當增加或移除子系統時需要修改外觀類,這違背了“開閉原則”。如果引入抽象外觀類(或介面),則在一定程度上解決了該問題,其結構圖如圖所示: