设计模式之外观模式(十一)

一、描述

        有很多子系统模块,不想让客户端直接去访问它们,定义一个外观类,通过访问这个外观类类调用子系统模块的功能。

二、优劣势


优点:降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口。减少系统相互依赖、提高灵活性。 提高了安全性。
缺点:违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类。

三、需求

      博物馆监控系统,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里的方法就可以了,总结一句话就是我们需要额外添加一个监控场所布置,设备数量和之前的不同,就创建一个新的监控外观类就可以了,这样就不需要去修改原来的,符合开闭原则。

八、总结

        一语道破:原来保安需要去摄像头、灯泡、警报器的位置里一次开启开关,跑来跑去累死了,引入我们的外观模式,就好比给他配置了一个电脑,只需要用鼠标点一下一键开启所有开关就可以了,舒舒服服的坐在办公室里遥控,也不需要去跟那些摄像头灯泡等打交道了。

觉得有用就留下评论吧^-^

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值