3、外观模式总结
引入了外观类,解除了客户类与子系统的耦合性。客户类不需要直接操作子系统,而是由外观类负责处理,对客户端而言是透明的,客户类只需要操作外观类就可以了,符合"迪迷特法则"。如果多个地方需要Facade,也就是说外观可以实现功能的共享,也就是实现复用,同样的调用代码只用在Facade里面写一次就好了,不用在多个调用的地方重复写。如果某个系统模块需要修改,只需要修改这个系统模块就可以了,对客户端无影响,维护性好。还有一个潜在好处,对使用Facade的人员来说,Facade节省了他们的学习成本,他们只需要了解Facade即可,无需深入到子系统内部,去了解每个模块的细节,也不用和多个模块交互,从而使得开发简单,学习也容易。
现在的系统是越做越大,越来越复杂,对软件的要求也越来越高。为了提高系统的可重用性,通常会把一个大的系统分为多个子系统,再把一个子系统分成很多更小的子系统,一直分下去,分到一个个小的模块,这样一来子系统的重用性就会得到加强。但这也带来一个问题,由于模块增加,对象之间的耦合性也随之增强了。外观模式可以解决这个问题,由外观来对各个子模块子系统进行处理,客户端只需要操作外观就可以了。
通常在三层架构中就需要考虑在数据访问层和业务逻辑层、业务逻辑层和UI层的层与层之间建立外观Facade,这样可以为复杂的子系统提供一个简单的结构,使得耦合大大降低。例如:在UI层定义一个外观对象,外观负责对应用层的子系统进行处理,当UI层有请求时,通过UI层的外观委托给应用层的子系统进行处理。同样可以在应用层定义一个外观对象,当应用层请求对数据进行处理的时候,通过应用层的外观委托给数据层中的模块对数据进行处理。
外观模式的主要优点如下:
(1) 它对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。通过引入外观模式,客户端代码将变得很简单,与之关联的对象也很少,符合“迪米特法则”。
(2) 它实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
(3) 一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
(4)外观对象负责对子系统进行处理,如果某个子系统进行了修改,可能只需要修改外观对象就可以了,维护性好。如果没有使用外观对象,则某个子系统进行了修改,则如果有多个客户端使用到这个子系统,则这些客户端都得进行修改,维护性差。
(5)多个客户端可以复用外观Facade,复用性好。
(6)符合多用组合少用继承原则。
外观模式的主要缺点如下:
(1) 不能很好地限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活 性。
(2) 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则。
3. 外观模式适用场景
(1) 当要为访问一系列复杂的子系统提供一个简单入口时可以使用外观模式。
(2) 客户端程序与多个子系统之间存在很大的依赖性。引入外观类可以将子系统与客户端解耦,从而提高子系统的独立性和可移植性。
(3) 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度
4.外观模式具体应用
(1)邮件业务系统的开发: 发信人只需要把发送内容,接收地址告诉邮局,邮局系统代为发送处理。邮局系统充当外观角色。
(2)绝大多数系统都有一个首页或者导航页面,同时也提供了菜单或者工具栏,在这里,首页和导航页面、菜单和工具栏就是外观角色,通过它们用户可以快速访问子系统,降低了系统的复杂程度。
(3)KTV点歌系统的开发: 提供一个外观用来处理显示器模块、音响模块、灯光模块操作。
(4)文件安全传送模块开发: 存在三个模块,读取文件内容模块,对文件内容进行加密模块和写入文件模块。提供一个外观,对这些模块进行处理。
(5)在三层架构中,UI层和业务逻辑层提供一个外观,业务逻辑层和数据访问层提供一个外观,这样可以为复杂的子系统提供一个简单的结构。
(6)车票订购系统的开发: 顾客只需要到售票窗口,购买所需要的火车票,汽车票、飞机票。由售票窗口统一处理。
(7)医疗系统的开发: 目前需要挂号、缴费、取药等流程。可以定义一个外观,让外观处理这些流程。
(8)Windows开机启动程序: 应用程序可以双击开启,也可以由Winodws代为处理,windows开机自动运行应用程序,这个时候,Windows系统就是一个外观。
(9)游戏充值系统的开发: 需要判断账号是否存在模块,判断库存是否充足模块,充值模块。提供一个外观负责和这三个模块打交道。
(10)生活中的外观: 找电脑组装公司组装电脑; 通过中介来处理房屋的买卖;开学需要办理各种手续流程,可以找人代为处理;公司需要开发某款产品,市场部门负责市场调研、采购部门负责采购配件,开发部门负责开发,这个时候,由总监代为处理各个部门的活动。