Unity入門設計模式之外觀模式(十一)

一、描述

        有很多子系統模塊,不想讓客戶端直接去訪問它們,定義一個外觀類,通過訪問這個外觀類類調用子系統模塊的功能。

二、優劣勢


優點:降低訪問複雜系統的內部子系統時的複雜度,簡化客戶端與之的接口。減少系統相互依賴、提高靈活性。 提高了安全性。
缺點:違背了“開閉原則”,當增加新的子系統或者移除子系統時需要修改外觀類。

三、需求

      博物館監控系統,2個攝像頭,2個燈泡,1個警報器,每次開館和閉館時都要控制它們狀態。


四、不使用設計模式

        都不考慮設計了,直接擼代碼。

        3個類,

        SheXiangTou.cs  -攝像頭類  

        DengPao.cs  -燈泡類  

        JingBaoQi.cs  -警報器類

//攝像頭
public class SheXiangTou
{
    private string name;
    public SheXiangTou(string s)
    {
        name = s;
    }
    public void Open()
    {
        Debug.Log("攝像頭-"+name + "開啓");
    }

    public void Close()
    {
        Debug.Log("攝像頭-"+name + "關閉");
    }
}

//燈泡
public class DengPao
{
    private string name;
    public DengPao(string s)
    {
        name = s;
    }
    public void Open()
    {
        Debug.Log("燈泡-" + name + "開啓");
    }

    public void Close()
    {
        Debug.Log("燈泡-" + name + "關閉");
    }
}

//警報器
public class JingBaoQi
{
    private string name;
    public JingBaoQi(string s)
    {
        name = s;
    }
    public void Open()
    {
        Debug.Log("警報器-" + name + "開啓");
    }

    public void Close()
    {
        Debug.Log("警報器-" + name + "關閉");
    }
}

//客戶端調用
    public static void main(string[] args)
    {
        SheXiangTou sheXiangTou1 = new SheXiangTou("高清");
        SheXiangTou sheXiangTou2 = new SheXiangTou("超高清");
        DengPao dengPao1 = new DengPao("強光");
        DengPao dengPao2 = new DengPao("弱光");
        JingBaoQi jingBaoQi = new JingBaoQi("防盜");

        Debug.Log("開館了");
        sheXiangTou1.Open();
        sheXiangTou2.Open();
        dengPao1.Open();
        dengPao2.Open();
        jingBaoQi.Open();

        Debug.Log("---------分割線---------");
        Debug.Log("8小時過去了");
        Debug.Log("閉館了");
        sheXiangTou1.Close();
        sheXiangTou2.Close();
        dengPao1.Close();
        dengPao2.Close();
        jingBaoQi.Close();
    }

運行結果

小結:可以看到在客戶端調用時非常麻煩,得手動去生成,並且一個一個的調用open,特別繁瑣。

 

五、使用設計模式

        通過添加一個外觀介,把子系統都放在裏面,並提供外部訪問接口(方法)去調用它們。       

        4個類,

        SheXiangTou.cs  -攝像頭類  

        DengPao.cs  -燈泡類  

        JingBaoQi.cs  -警報器類

        MonitorFacade.cs  -監控系統中介類

//攝像頭
public class SheXiangTou
{
    private string name;
    public SheXiangTou(string s)
    {
        name = s;
    }
    public void Open()
    {
        Debug.Log("攝像頭-"+name + "開啓");
    }

    public void Close()
    {
        Debug.Log("攝像頭-"+name + "關閉");
    }
}

//燈泡
public class DengPao
{
    private string name;
    public DengPao(string s)
    {
        name = s;
    }
    public void Open()
    {
        Debug.Log("燈泡-" + name + "開啓");
    }

    public void Close()
    {
        Debug.Log("燈泡-" + name + "關閉");
    }
}

//警報器
public class JingBaoQi
{
    private string name;
    public JingBaoQi(string s)
    {
        name = s;
    }
    public void Open()
    {
        Debug.Log("警報器-" + name + "開啓");
    }

    public void Close()
    {
        Debug.Log("警報器-" + name + "關閉");
    }
}

//監控系統中介類
public class MonitorFacade
{
    SheXiangTou sheXiangTou1;
    SheXiangTou sheXiangTou2;
    DengPao dengPao1;
    DengPao dengPao2;
    JingBaoQi jingBaoQi;

    public void Init()
    {
        sheXiangTou1 = new SheXiangTou("高清");
        sheXiangTou2 = new SheXiangTou("超高清");
        dengPao1 = new DengPao("強光");
        dengPao2 = new DengPao("弱光");
        jingBaoQi = new JingBaoQi("防盜");
        Debug.Log("監控系統初始化完畢");
    }

    public void Open()
    {       
        sheXiangTou1.Open();
        sheXiangTou2.Open();
        dengPao1.Open();
        dengPao2.Open();
        jingBaoQi.Open();
    }

    public void Close()
    {
        sheXiangTou1.Close();
        sheXiangTou2.Close();
        dengPao1.Close();
        dengPao2.Close();
        jingBaoQi.Close();
    }
}

//客戶端調用
public static void main(string[] args)
{
    MonitorFacade monitorFacade = new MonitorFacade();
    monitorFacade.Init();

    Debug.Log("開館了");
    monitorFacade.Open();

    Debug.Log("---------分割線---------");
    Debug.Log("8小時過去了");
    Debug.Log("閉館了");
    monitorFacade.Close();
}

運行結果

小結:我們通過新加一個監控類,然後在裏面進行統一的初始化,開關控制,這樣客戶端調用就方便了很多,只需要操作監控類就可以控制全部系統了,這裏的監控類就是我們的外觀模式。注意下監控類裏不只是只能有Open和Close方法,可根據具體需求去擴展,比如只打開攝像頭OpenSheXiangTou(),再把攝像頭的開啓調用寫裏面就好了。

六、設計圖

通過學習,我們瞭解到了外觀者模式的應用,我們把剛剛的實現方式畫出來。

七、進階講解

       剛剛說了外觀模式的弊端在於違反了開閉原則,也就是說如果我們想要再加一個紅外線設備進來,那麼我們要修改的地方有:MonitorFacade新加一個紅外線變量,並且修改Init(),Open(),Close()裏的方法,都要加上紅外線的開關調用。爲了解決這種反覆修改的問題,我們把抽象出一個外觀類基類Facade.cs,並且添加可重載方法Init、Open、Close,我們剛剛那個MonitorFacade去繼承它,然後新的需求是增加一個紅外線,那麼我們就再創建一個NewMonitorFacade類也繼承Facade,把紅外線的也給它加進去,然後客戶端那邊聲明 Facade facade,看看實際需求是要Facade facade= new MonitorFacade(),還是Facade facade= new NewMonitorFacade(),然後再調用facade裏的方法就可以了,總結一句話就是我們需要額外添加一個監控場所佈置,設備數量和之前的不同,就創建一個新的監控外觀類就可以了,這樣就不需要去修改原來的,符合開閉原則。

八、總結

        一語道破:原來保安需要去攝像頭、燈泡、警報器的位置裏一次開啓開關,跑來跑去累死了,引入我們的外觀模式,就好比給他配置了一個電腦,只需要用鼠標點一下一鍵開啓所有開關就可以了,舒舒服服的坐在辦公室裏遙控,也不需要去跟那些攝像頭燈泡等打交道了。

覺得有用就留下評論吧^-^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章