结构型模式 - 外观模式Facade

1、tm的NT审核机制,满篇文章哪来的广告? 就算有也是你们自己加的吧?等财富能支持我自己的网站后,就是和你们说再见之时。
2、tm第二遍说,我接着提交,这个审核机制的傻逼设计者或者是程序敲出来的bug。
3、广告广告广你老母亲的告?   我都三边发,你倒是告诉我哪里有广告啊

学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。

目标

      软件设计也是这样,当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。

外观模式的定义与特点

     外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。  

      在日常编码工作中,我们都在有意无意的大量使用外观模式。只要是高层模块需要调度多个子系统(2个以上的类对象),我们都会自觉地创建一个新的类封装这些子系统,提供精简的接口,让高层模块可以更加容易地间接调用这些子系统的功能。尤其是现阶段各种第三方SDK、开源类库,很大概率都会使用外观模式。  

外观(Facade)模式是“迪米特法则”的典型应用,它有以下主要优点。

  • 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
  • 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
  • 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。

外观(Facade)模式的主要缺点如下。

  • 不能很好地限制客户使用子系统类,很容易带来未知风险。
  • 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

外观模式的结构与实现

        外观(Facade)模式的结构比较简单,主要是定义了一个高层接口。它包含了对各个子系统的引用,客户端可以通过它访问各个子系统的功能。现在来分析其基本结构和实现方法。

1. 模式的结构

外观(Facade)模式包含以下主要角色。

  1. 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
  2. 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
  3. 客户(Client)角色:通过一个外观角色访问各个子系统的功能。

其结构图如图 1 所示。

图1

 代码

using DesignPattern.FacadePattern;
using System;

namespace DesignPattern
{
    internal class Program
    {
        static void Main(string[] args)
        {
            FacadeHelper();
        }

        #region Pattern - Facade
        static void FacadeHelper()
        {
            FacadeMode facade = new FacadeMode();

            facade.BackHome();
            facade.GoSleep();
            facade.GoWork();

            Console.ReadLine();
        }
        #endregion
    }
}

//======================================================================================

using System;

namespace DesignPattern.FacadePattern
{
    /// <summary>
    /// 外观接口
    /// </summary>
    internal interface IFacade
    {
        /// <summary>
        /// 打开
        /// </summary>
        void Open();

        /// <summary>
        /// 关闭
        /// </summary>
        void Close();
    }

    /// <summary>
    /// 窗户
    /// </summary>
    public class Window : IFacade
    {
        public void Close()
        {
            Console.WriteLine("关闭窗户");
        }

        public void Open()
        {
            Console.WriteLine("打开窗户");
        }
    }

    /// <summary>
    /// 无线网络
    /// </summary>
    public class Wifi : IFacade
    {
        public void Close()
        {
            Console.WriteLine("关闭Wifi");
        }

        public void Open()
        {
            Console.WriteLine("打开Wifi");
        }
    }

    /// <summary>
    /// 闹钟
    /// </summary>
    public class Alarm : IFacade
    {
        public void Close()
        {
            Console.WriteLine("关闭闹铃");
        }

        public void Open()
        {
            Console.WriteLine("打开闹铃");
        }
    }

    /// <summary>
    /// 对外窗口
    /// </summary>
    public class FacadeMode
    {
        private Window m_window;
        private Wifi m_wifi;
        private Alarm m_alarm;

        /// <summary>
        /// 对外窗口
        /// </summary>
        public FacadeMode()
        {
            m_window = new Window();
            m_wifi = new Wifi();
            m_alarm = new Alarm();
        }

        /// <summary>
        /// 到家
        /// </summary>
        public void BackHome()
        {
            Console.WriteLine("Xiaohei is back.");
            m_window.Open();
            m_wifi.Open();
            m_alarm.Close();
        }

        /// <summary>
        /// 该睡觉
        /// </summary>
        public void GoSleep()
        {
            Console.WriteLine("Should be sleep.");
            m_window.Close();
            m_wifi.Close();
            m_alarm.Open();
        }

        /// <summary>
        /// 去工作
        /// </summary>
        public void GoWork()
        {
            Console.WriteLine("Wow,go to work.");
            m_window.Close();
            m_wifi.Close();
            m_alarm.Close();
        }
    }
}
运行结果

与代理模式之间的异同

相同点

  • 都可以在不改变子系统代码的基础上,对子系统加以控制。
  • 原有系统之间都是可以直接访问的,两个模式都是为了让子系统更加容易使用。
  • 都不应该在其中添加子系统没有的功能。

不同点

  • 外观模式面向的是多条个不同的子系统,而代理模式通常面向的是一个(或者多个相同的)子系统。
  • 外观模式更多强调的是对多个子系统的整合,而代理模式更多强调的是对某个子系统的代理。

极端情况下,例如外观模式中的子系统只有一个,就跟代理模式差不多了,这有点像抽象工厂模式工厂方法模式之间的关系。

总结:

       外观模式其实就象是我们的生活中已经设置好的小爱同学

  1. 我到家了,它会帮我开电脑,订好晚上洗漱和该睡觉的闹铃。
  2. 我说晚安,它会帮我关灯、会设置好2个小时后的关空调、会设置好早晨的起床闹铃,会放半个小时的催眠曲。
  3. 早晨我让它播放早报,它会同时设置好我下班前半个小时打开空调、会关闭除自身外的电源总控。

这么一说,小爱同学是我生活中不可缺少的一部分啊。


希望大家:点赞,留言,关注咯~    
😘😘😘😘

唠家常

今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加QQ:841298494,大家一起进步。

  • 客官,看完get之后记得点赞哟!
  • 小伙伴你还想要别的知识?好的呀,分享给你们😄

今日推荐

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫磊落长歌行

觉得小黑这篇文章不赖,打赏哟~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值