溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發(fā)布時間:2020-06-17 19:44:47 來源:網(wǎng)絡 閱讀:1282 作者:LearningHard 欄目:編程語言

一、引言

在軟件開發(fā)過程中,客戶端程序經(jīng)常會與復雜系統(tǒng)的內(nèi)部子系統(tǒng)進行耦合,從而導致客戶端程序隨著子系統(tǒng)的變化而變化,然而為了將復雜系統(tǒng)的內(nèi)部子系統(tǒng)與客戶端之間的依賴解耦,從而就有了外觀模式,也稱作 ”門面“模式。下面就具體介紹下外觀模式。

二、外觀模式的詳細介紹

2.1 定義

外觀模式提供了一個統(tǒng)一的接口,用來訪問子系統(tǒng)中的一群接口。外觀定義了一個高層接口,讓子系統(tǒng)更容易使用。使用外觀模式時,我們創(chuàng)建了一個統(tǒng)一的類,用來包裝子系統(tǒng)中一個或多個復雜的類,客戶端可以直接通過外觀類來調(diào)用內(nèi)部子系統(tǒng)中方法,從而外觀模式讓客戶和子系統(tǒng)之間避免了緊耦合。

2.2 外觀模式實現(xiàn)

介紹了外觀模式的定義之后,讓我們具體看看外觀模式的由來以及實現(xiàn),下面與學校中一個選課系統(tǒng)為例來解釋外觀模式,例如在選課系統(tǒng)中,有注冊課程子系統(tǒng)和通知子系統(tǒng),在不使用外觀模式的情況下,客戶端必須同時保存注冊課程子系統(tǒng)和通知子系統(tǒng)兩個引用,如果后期這兩個子系統(tǒng)發(fā)生改變時,此時客戶端的調(diào)用代碼也要隨之改變,這樣就沒有很好的可擴展性,下面看看不使用外觀模式下選課系統(tǒng)的實現(xiàn)方式和客戶端調(diào)用代碼:

/// <summary>
    /// 不使用外觀模式的情況
    /// 此時客戶端與三個子系統(tǒng)都發(fā)送了耦合,使得客戶端程序依賴與子系統(tǒng)
    /// 為了解決這樣的問題,我們可以使用外觀模式來為所有子系統(tǒng)設計一個統(tǒng)一的接口
    /// 客戶端只需要調(diào)用外觀類中的方法就可以了,簡化了客戶端的操作
    /// 從而讓客戶和子系統(tǒng)之間避免了緊耦合
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {
            SubSystemA a = new SubSystemA();
            SubSystemB b = new SubSystemB();
            SubSystemC c = new SubSystemC();
            a.MethodA();
            b.MethodB();
            c.MethodC();
            Console.Read();
        }
    }
    // 子系統(tǒng)A
    public class SubSystemA
    {
        public void MethodA()
        {
            Console.WriteLine("執(zhí)行子系統(tǒng)A中的方法A");
        }
    }
    // 子系統(tǒng)B
    public class SubSystemB
    {
        public void MethodB()
        {
            Console.WriteLine("執(zhí)行子系統(tǒng)B中的方法B");
        }
    }
    // 子系統(tǒng)C
    public class SubSystemC
    {
        public void MethodC()
        {
            Console.WriteLine("執(zhí)行子系統(tǒng)C中的方法C");
        }
    }

然而外觀模式可以解決我們上面所說的問題,下面具體看看使用外觀模式的實現(xiàn):

/// <summary>
    /// 以學生選課系統(tǒng)為例子演示外觀模式的使用
    /// 學生選課模塊包括功能有:
    /// 驗證選課的人數(shù)是否已滿
    /// 通知用戶課程選擇成功與否
    /// 客戶端代碼
    /// </summary>
    class Student
    {
        private static RegistrationFacade facade = new RegistrationFacade();
        static void Main(string[] args)
        {
            if (facade.RegisterCourse("設計模式", "Learning Hard"))
            {
                Console.WriteLine("選課成功");
            }
            else
            {
                Console.WriteLine("選課失敗");
            }
            Console.Read();
        }
    }
    // 外觀類
    public class RegistrationFacade
    {
        private RegisterCourse registerCourse;
        private NotifyStudent notifyStu;
        public RegistrationFacade()
        {
            registerCourse = new RegisterCourse();
            notifyStu = new NotifyStudent();
        }
        public bool RegisterCourse(string courseName, string studentName)
        {
            if (!registerCourse.CheckAvailable(courseName))
            {
                return false;
            }
            return notifyStu.Notify(studentName);
        }
    }
    #region 子系統(tǒng)
    // 相當于子系統(tǒng)A
    public class RegisterCourse
    {
        public bool CheckAvailable(string courseName)
        {
            Console.WriteLine("正在驗證課程 {0}是否人數(shù)已滿", courseName);
            return true;
        }
    }
    // 相當于子系統(tǒng)B
    public class NotifyStudent
    {
        public bool Notify(string studentName)
        {
            Console.WriteLine("正在向{0}發(fā)生通知", studentName);
            return true;
        }
    }
    #endregion

使用了外觀模式之后,客戶端只依賴與外觀類,從而將客戶端與子系統(tǒng)的依賴解耦了,如果子系統(tǒng)發(fā)生改變,此時客戶端的代碼并不需要去改變。外觀模式的實現(xiàn)核心主要是——由外觀類去保存各個子系統(tǒng)的引用,實現(xiàn)由一個統(tǒng)一的外觀類去包裝多個子系統(tǒng)類,然而客戶端只需要引用這個外觀類,然后由外觀類來調(diào)用各個子系統(tǒng)中的方法。然而這樣的實現(xiàn)方式非常類似適配器模式,然而外觀模式與適配器模式不同的是:適配器模式是將一個對象包裝起來以改變其接口,而外觀是將一群對象 ”包裝“起來以簡化其接口。它們的意圖是不一樣的,適配器是將接口轉(zhuǎn)換為不同接口,而外觀模式是提供一個統(tǒng)一的接口來簡化接口。

2.3 外觀模式的結(jié)構(gòu)

看完外觀模式的實現(xiàn)之后,為了幫助理清外觀模式中類之間的關(guān)系,下面給出上面實現(xiàn)代碼中類圖:

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

然而對于外觀模式而言,是沒有一個一般化的類圖描述,下面演示一個外觀模式的示意性對象圖來加深大家對外觀模式的理解:

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

在上面的對象圖中有兩個角色:

門面(Facade)角色客戶端調(diào)用這個角色的方法。該角色知道相關(guān)的一個或多個子系統(tǒng)的功能和責任,該角色會將從客戶端發(fā)來的請求委派帶相應的子系統(tǒng)中去。

子系統(tǒng)(subsystem)角色可以同時包含一個或多個子系統(tǒng)。每個子系統(tǒng)都不是一個單獨的類,而是一個類的集合。每個子系統(tǒng)都可以被客戶端直接調(diào)用或被門面角色調(diào)用。對于子系統(tǒng)而言,門面僅僅是另外一個客戶端,子系統(tǒng)并不知道門面的存在。

三、外觀的優(yōu)缺點

優(yōu)點:

  1. 外觀模式對客戶屏蔽了子系統(tǒng)組件,從而簡化了接口,減少了客戶處理的對象數(shù)目并使子系統(tǒng)的使用更加簡單。

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

缺點:

  1. 如果增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼,這樣就違背了”開——閉原則“(不過這點也是不可避免)。

四、使用場景

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

  • 外一個復雜的子系統(tǒng)提供一個簡單的接口

  • 提供子系統(tǒng)的獨立性

  • 在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口。其中三層架構(gòu)就是這樣的一個例子。

五、總結(jié)

到這里外觀模式的介紹就結(jié)束了,外觀模式,為子系統(tǒng)的一組接口提供一個統(tǒng)一的接口,該模式定義了一個高層接口,這一個高層接口使的子系統(tǒng)更加容易使用。并且外觀模式可以解決層結(jié)構(gòu)分離、降低系統(tǒng)耦合度和為新舊系統(tǒng)交互提供接口功能。


附件:http://down.51cto.com/data/2363651
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI