本笔记摘抄自: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 } }