C#設計模式-外觀模式(Facade Pattern)

引言

在軟體測試中,一般都是在功能測試穩定的情況下再進行UI自動化測試、或者進行性能測試。如果一個一個進行太麻煩,此時可以使用對外提供一個簡單介面,通過這個介面可以訪問內部一群介面。例如進行UI自動化測試, 那麼執行功能測試後再執行自動化測試。在軟體開發過程中,將對外提供了一個統一的介面,用來訪問子系統中的一群介面的模式稱為外觀模式。這種模式可以應對客戶端程式與複雜系統的內部子系統進行耦合而導致客戶端程式隨著子系統的變化而變化,將複雜系統的內部子系統與客戶端之間的依賴解耦。

概念

外觀模式(Facade Pattern)是一種結構型設計模式, 能為複雜系統、 程式庫或框架提供一個簡單 (但有限) 的介面。

外觀定義了一個高層介面,讓子系統更容易使用。使用外觀模式時,我們創建了一個統一的類,用來包裝子系統中一個或多個複雜的類,客戶端可以直接通過外觀類來調用內部子系統中方法,從而外觀模式讓客戶和子系統之間避免了緊耦合。

結構圖

角色

外觀角色(Facade):在客戶端可以調用它的方法,在外觀角色中可以知道相關的(一個或者多個)子系統的功能和責任;在正常情況下,它將所有從客戶端發來的請求委派到相應的子系統去,傳遞給相應的子系統對象處理。
子系統角色(SubSystem Classes):在軟體系統中可以有一個或者多個子系統角色,每一個子系統可以不是一個單獨的類,而是一個類的集合,它實現子系統的功能;每一個子系統都可以被客戶端直接調用,或者被外觀角色調用,它處理由外觀類傳過來的請求;子系統並不知道外觀的存在,對於子系統而言,外觀角色僅僅是另外一個客戶端而已。

實現

例如我們實現引言中提到的手動測試、自動化測試、性能測試。

using System;


namespace Facade
{
    class Program
    {
        /// <summary>
        /// 如果不使用外觀模式,則需要調用三次測試執行
        /// 此時客戶端只需要調用外觀類中的方法就可以了,簡化了客戶端的操作
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            StartTest test = new StartTest();
            test.start();

            Console.Read();
        }
    }



    /// <summary>
    /// 外觀類,開始測試
    /// </summary>
    public class StartTest
    {
        private ManuaTest manua;
        private AutoTest auto;
        private StressTest stress;

        public StartTest()
        {
            manua = new ManuaTest();
            auto = new AutoTest();
            stress = new StressTest();
        }

        public void start()
        {
            manua.test();
            auto.test();
            stress.test();
        }
    }

    /// <summary>
    /// 子系統類A,手工測試
    /// </summary>
    public class ManuaTest
    {
        public void test()
        {
            Console.WriteLine("執行手工測試");
        }
    }

    /// <summary>
    /// 子系統類B,自動化測試
    /// </summary>
    public class AutoTest
    {
        public void test()
        {
            Console.WriteLine("執行自動化測試");
        }
    }

    /// <summary>
    /// 子系統類C,壓力測試
    /// </summary>
    public class StressTest
    {
        public void test()
        {
            Console.WriteLine("執行壓力測試");
        }
    }
}

運行結果

執行手工測試
執行自動化測試
執行壓力測試

優缺點

優點

  • 外觀模式降低了客戶端對子系統使用的複雜性。一個子系統的修改對其他子系統沒有任何影響,而且子系統內部變化也不會影響到外觀對象。
  • 外觀模式鬆散了客戶端與子系統的耦合關係,讓子系統內部的模組能更容易擴展和維護。
  • 通過合理使用外觀模式,可以幫助我們更好的劃分訪問的層次。

 缺點  

  • 不能很好地限制客戶端直接使用子系統類,如果對客戶端訪問子系統類做太多的限制則減少了可變性和靈活 性。
  • 如果設計不當,增加新的子系統可能需要修改外觀類的源程式碼,違背了開閉原則。

適用場景

  • 當要為訪問一系列複雜的子系統提供一個簡單入口時可以使用外觀模式。
  • 客戶端程式與多個子系統之間存在很大的依賴性。引入外觀類可以將子系統與客戶端解耦,從而提高子系統的獨立性和可移植性。
  • 在層次化結構中,可以使用外觀模式定義系統中每一層的入口,層與層之間不直接產生聯繫,而通過外觀類建立聯繫,降低層之間的耦合度。