结构型模式 - 外观模式Facade
1、tm的NT审核机制,满篇文章哪来的广告? 就算有也是你们自己加的吧?等财富能支持我自己的网站后,就是和你们说再见之时。
2、tm第二遍说,我接着提交,这个审核机制的傻逼设计者或者是程序敲出来的bug。
3、广告广告广你老母亲的告? 我都三边发,你倒是告诉我哪里有广告啊
学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。
目标
软件设计也是这样,当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
外观模式的定义与特点
外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
在日常编码工作中,我们都在有意无意的大量使用外观模式。只要是高层模块需要调度多个子系统(2个以上的类对象),我们都会自觉地创建一个新的类封装这些子系统,提供精简的接口,让高层模块可以更加容易地间接调用这些子系统的功能。尤其是现阶段各种第三方SDK、开源类库,很大概率都会使用外观模式。
外观(Facade)模式是“迪米特法则”的典型应用,它有以下主要优点。
- 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
- 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
- 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
外观(Facade)模式的主要缺点如下。
- 不能很好地限制客户使用子系统类,很容易带来未知风险。
- 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
外观模式的结构与实现
外观(Facade)模式的结构比较简单,主要是定义了一个高层接口。它包含了对各个子系统的引用,客户端可以通过它访问各个子系统的功能。现在来分析其基本结构和实现方法。
1. 模式的结构
外观(Facade)模式包含以下主要角色。
- 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
- 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
- 客户(Client)角色:通过一个外观角色访问各个子系统的功能。
其结构图如图 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();
}
}
}

与代理模式之间的异同
相同点
- 都可以在不改变子系统代码的基础上,对子系统加以控制。
- 原有系统之间都是可以直接访问的,两个模式都是为了让子系统更加容易使用。
- 都不应该在其中添加子系统没有的功能。
不同点
- 外观模式面向的是多条个不同的子系统,而代理模式通常面向的是一个(或者多个相同的)子系统。
- 外观模式更多强调的是对多个子系统的整合,而代理模式更多强调的是对某个子系统的代理。
极端情况下,例如外观模式中的子系统只有一个,就跟代理模式差不多了,这有点像抽象工厂模式和工厂方法模式之间的关系。
总结:
外观模式其实就象是我们的生活中已经设置好的小爱同学:
- 我到家了,它会帮我开电脑,订好晚上洗漱和该睡觉的闹铃。
- 我说晚安,它会帮我关灯、会设置好2个小时后的关空调、会设置好早晨的起床闹铃,会放半个小时的催眠曲。
- 早晨我让它播放早报,它会同时设置好我下班前半个小时打开空调、会关闭除自身外的电源总控。
这么一说,小爱同学是我生活中不可缺少的一部分啊。
希望大家:点赞,留言,关注咯~
😘😘😘😘
唠家常
今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加我QQ:841298494,大家一起进步。
- 客官,看完get之后记得点赞哟!
- 小伙伴你还想要别的知识?好的呀,分享给你们😄
今日推荐
本文来自博客园,作者:青衫磊落长歌行,转载请注明原文链接:https://www.cnblogs.com/WenhaoWang/p/17073499.html
身负灵石行天下,冲关断喝辨正邪; 仙籍经文誊卷上,日省三身驭鬼神; 奇门遁甲游四方,九星八门断吉凶; 仙宝葫芦聚灵兽,乾坤凝练化神火; 八卦灵镜控震雷,凛然正气荡妖魔; 虚怀若谷尝百草,岐黄妙术展幡旗; 祈符笔走通九幽,素手悬铃摄心魂; 依剑证道心通明,青衫磊落长歌行。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步