本笔记摘抄自: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. springboot的yml不显示的原因

    首先排除插件原因 1 安装好插件Ctrl+Alt+S 2 查看修改的application.yml是什么格 在yaml格式中添加*.yaml和*.yml 3 查看maven是否配置完善

  2. 洛谷P3335 [ZJOI2013]蚂蚁寻路

    题目描述 在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯前走了多长. 蚂蚁转弯是有一定特点的,即它的转弯序 ...

  3. xsd 和 wsdl

    xsd : 可用方便 不同的语言之间的 用命令行来 转换对应语言的. wsdl: 可用方便不同语言的类描述 用命令行 来相互转换. 类似 thift me ?

  4. c#数字图像处理(一)Bitmap类、 Bitmapdata类和 Graphics类

    Bitmap类. Bitmapdata类和 Graphics类是C#图像处理中最重要的3个类,如果要用C#进行图像处理,就一定要掌握它们. 1.1 Bitmap类Bitmap对象封装了GDI+中的一个 ...

  5. Dynamics 365 CRM Action 和 workflow 的区别

    workflow 总是需要一个record作为起始点(create, update, delete or on-demand) 但是action 不需要. 例如我们需要action来创建一个发送ema ...

  6. Redhat6.7 切换Centos yum源

    转自:http://inlhx.iteye.com/blog/2336729 RedHat 更换Yum源 1.检查yum包 rpm -qa |grep yum 2.删除自带包 rpm -aq | gr ...

  7. Http请求特殊符号变空格

    Http请求特殊符号变空格 今天在调试客户端向服务器传递参数时,url中的参数值出现+,空格,/,?,%,#,&等特殊符号的时候就自动变成空格,在服务器端无法获得正确的参数值.解决方法如下: ...

  8. K8S部署遇到的问题处理汇总

    第一个: node节点注册提示:failed to get config map: Unauthorized 代码如下: [root@node1 ~]# kubeadm join --token ll ...

  9. 【Detection】物体识别-制作PASCAL VOC数据集

    PASCAL VOC数据集 PASCAL VOC为图像识别和分类提供了一整套标准化的优秀的数据集,从2005年到2012年每年都会举行一场图像识别challenge 默认为20类物体 1 数据集结构 ...

  10. python笔记带你走向测试开发之路-第一篇(数据类型之数字,序列)

    数字 数字的类型 数字是 Python中比较常用的数据类型,数字有可以分为: 整型 int如 1,2,3 浮点型 float如 2.1,3.5 长整型 long如 3L,需要注意的是 Python2. ...