本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7772184.html,记录一下学习过程以备后续查用。

一、引言

今天我们要讲结构型设计模式的第五个模式--外观模式。先从名字上来理解一下外观模式,当看到“外观”这个词时,很容易想到“外表”这个词语,两者有着

很相近的意思。就拿谈恋爱来说,“外表”很重要,如果第一眼看着很舒服、有眼缘,那就有交往下去的可能。如果长得“三寸钉、枯树皮”,估计就够呛了。

在这方面,“外观”和“外表”有着相同的作用。在软件系统中,要完成一个功能如果需要调用很多接口,不仅增加了开发及调试难度,也增加了维护的复杂度。

如果把这些接口再封装一次,给一个很好的“外观”,让使用者只需调用一个接口,就可以完成以前调用多个接口来完成的任务,这样使用起来就方便多了。

这个模式很简单,大家很容易理解,可能大家在编码的过程中已经不止一次使用过该模式了,只是不知道名字罢了。现实生活中这样的例子很多,举不胜

举,来一幅图,大家看看就明白了。

    二、外观模式介绍

外观模式:英文名称--Facade Pattern;分类--结构型。

2.1、动机(Motivate)

在软件系统开发的过程中,当组件的客户(即外部接口或客户程序)和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这

种过多的耦合面临很多变化的挑战。如何简化外部客户程序和系统间的交互接口?如何将外部客户程序的演化和内部子系统的变化之间的依赖相互解耦?

2.2、意图(Intent)

为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。——《设计模式》GoF

2.3、结构图(Structure)

2.4、模式的组成

外观模式包含如下两个角色:

1)外观角色(Facade):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从

客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。

2)子系统角色(SubSystem):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统

的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观

角色仅仅是另外一个客户端而已。

2.5、外观模式的具体实现

马上就到“双11”了,人们又开始疯狂地购买了。其实购买的过程很复杂,但是我们在购买的过程只需要选择自己喜欢的商品,也可以加入购物车,最后点击

付款就完成了。其实这个过程没有那么简单,下面就模仿一下购买的过程吧。

购买过程有几点必须要做的事情:

1)身份认证,如果没有认证就是无效用户。

2)系统安全,检查系统环境,防止注入、跨站和伪造等攻击。

3)网银安全,检查付款地址的有效性,检查网关是否正常。

    class Program
{
/// <summary>
/// 身份认证子系统A
/// </summary>
public class AuthoriationSystemA
{
public void MethodA()
{
Console.WriteLine("执行身份认证。");
}
} /// <summary>
/// 系统安全子系统B
/// </summary>
public class SecuritySystemB
{
public void MethodB()
{
Console.WriteLine("执行系统安全检查。");
}
} /// <summary>
/// 网银安全子系统C
/// </summary>
public class NetBankSystemC
{
public void MethodC()
{
Console.WriteLine("执行网银安全检测。");
}
} /// <summary>
/// 更高层的Facade
/// </summary>
public class SystemFacade
{
private AuthoriationSystemA auth;
private SecuritySystemB security;
private NetBankSystemC netbank; public SystemFacade()
{
auth = new AuthoriationSystemA();
security = new SecuritySystemB();
netbank = new NetBankSystemC();
} public void Buy()
{
auth.MethodA(); //身份认证子系统
security.MethodB(); //系统安全子系统
netbank.MethodC(); //网银安全子系统 Console.WriteLine("我已经成功购买了。");
}
} static void Main(string[] args)
{
#region 外观模式
SystemFacade facade = new SystemFacade();
facade.Buy();
Console.Read();
#endregion
}
}

运行结果如下:

这个模式很简单,就话不多说了。

三、外观模式的实现要点

1)一个系统可以有几个外观类

在外观模式中,通常只需要一个外观类并且此外观类只有一个实例,换言之它是一个单例类。当然这并不意味着在整个系统里只有一个外观类,而仅仅是说

对每一个子系统只有一个外观类。或者说,如果一个系统有好几个子系统的话,每一个子系统都有一个外观类,整个系统可以有数个外观类。

2)为子系统增加新行为

初学者往往以为通过继承一个外观类便可在子系统中加入新的行为,这是错误的。外观模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能向

子系统加入新的行为。比如医院中的接待员并不是医护人员,接待员并不能为病人提供医疗服务。

3)Facade有助于建立层次结构的系统,实现了子系统与客户之间的松耦合关系,子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变

化不会影响到它的客户。Facade消除了复杂的循环依赖关系,这一点在客户程序与子系统分别实现的时候格外重要。

4)从客户程序的角度来看,Facade模式不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,从某种程度上也达到了一种“解耦”的效

果,因为内部子系统的任何变化不会影响到Facade接口的变化。

3.1、外观模式的优点

1)外观模式对客户屏蔽了子系统组件,从而简化了接口,减少了客户处理的对象数目并使子系统的使用更加简单。

2)外观模式实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件是紧耦合的。松耦合使得子系统的组件变化不会影响到它的客户。

3.2、外观模式的缺点

1)如果增加新的子系统可能需要修改外观类或客户端的源代码,这样就违背了”开闭原则“(不过这点也是不可避免)。

3.3、在以下情况下可以考虑使用外观模式

1)为一个复杂的子系统提供一个简单的接口。

2)提供子系统的独立性。

3)在层次化结构中,可以使用外观模式定义系统中每一层的入口,其中三层架构就是这样的一个例子。

四、.NET 中外观模式的实现

外观模式在FCL里面的运用还是很多的,多数情况是单个类的情况。在Asp.Net里面,有很多复合控件,比如:Login控件,可以登录、认证、保存登录用户

信息。其实,外观模式更多的是应用在业务系统当中,效果更好。

五、总结

这个模式很简单,就不说了,就稍微做一下小结。Facade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。Facade很多时候更是一种架

构设计模式。注意区分Facade模式、Adapter模式、Bridge模式与Decorator模式:

Facade模式注重简化接口

Adapter模式注重转换接口

Bridge模式注重分离接口(抽象)与其实现

Decorator模式注重稳定接口的前提下为对象扩展功能

C#设计模式学习笔记:(10)外观模式的更多相关文章

  1. 设计模式学习笔记--备忘录(Mamento)模式

    写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方式,这就是软件模式:每个模式描写叙述了一个在我们程序设计中常常发生的问题,以及该问题的解决方式:当我们碰到模 ...

  2. 《Head First 设计模式》学习笔记——适配器模式 + 外观模式

    在ADO.NET中.对于我们从数据库中取出的数据都要放到一个DataSet中,无论你是Access的数据库,还是SQL的数据库,或者是Oracle的数据库都要放到DataSet中..NET中并没有提供 ...

  3. 设计模式学习系列9 外观模式Facade

    1.概述 自己卖了一辆越野自行车,但毕竟不是自己定制的,买回来之后可能需要更改一下脚蹬,座皮,里程计数器或者刹车系统,假如将自行车看做一个整体系统,对我们而言使用的是自行车,然后我们对自己车构件的修改 ...

  4. 研磨设计模式学习笔记2--外观模式Facade

    需求:客户端需要按照需求,执行一个操作,操作包括一个系统中的3个模块(根据配置选择是否全部执行). 外观模式优点: 客户端无需知道系统内部实现,,只需要写好配置文件,控制那些模块执行,简单易用. 外观 ...

  5. 设计模式学习笔记-Adapter模式

    Adapter模式,就是适配器模式,使两个原本没有关联的类结合一起使用. 平时我们会经常碰到这样的情况,有了两个现成的类,它们之间没有什么联系,但是我们现在既想用其中一个类的方法,同时也想用另外一个类 ...

  6. Java-马士兵设计模式学习笔记-装饰者模式

    Java装饰者模式简介 一.假设有一个Worker接口,它有一个doSomething方法,Plumber和Carpenter都实现了Worker接口,代码及关系如下: 1.Worker.java p ...

  7. 设计模式学习笔记 1.factory 模式

    Factory 模式 用户不关心工厂的具体类型,只知道这是一个工厂就行. 通过工厂的实现推迟到子类里面去来确定工厂的具体类型. 工厂的具体类型来确定生产的具体产品. 同时用户不关心这是一个什么样子的产 ...

  8. 设计模式学习笔记——Composite 组合模式

    用于描述无限层级的复杂对象,类似于描述资源管理器,抽象出每一个层级的共同特点(文件夹和文件,展开事件) 以前描述一个对象,是将整个对象的全部数据都描述清楚,而组合模式通过在对象中定义自己,描述自己的下 ...

  9. 设计模式学习笔记——Bridge 桥接模式

    先说一下我以前对桥接模式的理解:当每个类中都使用到了同样的属性或方法时,应该将他们单独抽象出来,变成这些类的属性和方法(避免重复造轮子),当时的感觉是和三层模型中的model有点单相似,也就是让mod ...

  10. 设计模式学习笔记——Visitor 访问者模式

    1.定义IVisitor接口,确定变化所涉及的方法 2.封装变化类.实现IVisitor接口 3.在实体类的变化方法中传入IVisitor接口,由接口确定使用哪一种变化来实现(封装变化) 4.在使用时 ...

随机推荐

  1. Redis(六):list/lpush/lrange/lpop 命令源码解析

    上一篇讲了hash数据类型的相关实现方法,没有茅塞顿开也至少知道redis如何搞事情的了吧. 本篇咱们继续来看redis中的数据类型的实现: list 相关操作实现. 同样,我们以使用者的角度,开始理 ...

  2. PyCharm2019.3.2专业版激活

    PyCharm2019.3.2专业版激活 Ryan 蚂蚁小黑  PyCharm 专业版激活 今天是除夕,在这阖家团圆的日子里,祝大家新春快乐,鼠年大吉,愿大家在新的一年里身体健康,万事如意! 新的一年 ...

  3. FileZilla 报错“the server's certificate is unknown”

    FileZilla 是非常好用的一款FTP SFTP 管理工具. 但是filezilla会报错“the server's certificate is unknown” 并且会在window中看到以下 ...

  4. python实例:自动爬取豆瓣读书短评,分析短评内容

    思路: 1.打开书本“更多”短评,复制链接 2.脚本分析链接,通过获取短评数,计算出页码数 3.通过页码数,循环爬取当页短评 4.短评写入到txt文本 5.读取txt文本,处理文本,输出出现频率最高的 ...

  5. Commvault逻辑架构及组件说明

    在学习和使用Commvault软件的过程中,经常会碰到一些术语和缩写,初学者可能并不是很清楚这些术语和缩写的具体含义,接下来我们梳理一下Commvault软件中这些属于和缩写的含义,有可能一次不能梳理 ...

  6. [校内训练19_09_03]c Huge Counting

    题意 有一个定义在 k 维非负整点上的函数:$f(x_1,x_2,...,x_k):N_{0}^{k}->\{0,1\}$ ,定义方法如下: 若存在$j∈[1,k],x_j=0$,则$f(x_1 ...

  7. 清晰架构(Clean Architecture)的Go微服务: 编码风格

    编码风格在编程中是一个相对乏味的主题,但是合适的编码风格对一个有效的程序员是至关重要的. 它有三个组成部分: 程序结构 ( application layout) 编码规则或风格 命名约定 我已经在清 ...

  8. [白话解析] 带你一起梳理Word2vec相关概念

    [白话解析] 带你一起梳理Word2vec相关概念 0x00 摘要 本文将尽量使用易懂的方式,尽可能不涉及数学公式,而是从整体的思路上来说,运用感性直觉的思考来帮大家梳理Word2vec相关概念. 0 ...

  9. input输入框联想功能

    一直想找一个可以连接后台,可以根据后台内容的input输入框,可以实现联想功能,网上找到一个简单的静态页面的输入框联想,经过一番修改之后终于可以实现读取自己定义的数组的联想了,其实也比较简单就是格式的 ...

  10. C++内存管理笔记(一)

      C++内存分配的四个层面 : 四个层面的比较: 内存分配与释放的测试: ); //512 bytes free(p1); complex<int>* p2 = new complex& ...