定义:也叫外观模式,要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行.门面模式提供一个高层次的接口,使得子系统更易于使用.
类型:结构型模式
类图:
门面模式结构:
Facade门面角色:客户端可以调用这个角色的方法.此角色知晓子系统的所有功能和责任。一般情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去,也就说该角色没有实际的业务逻辑,只是一个委托类。
subsystem子系统角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。子系统并不知道门面的存在。对于子系统而言,门面仅仅是另外一个客户端而已。
通用代码实现:
// 子系统01,邮局接收信件的业务 class Subsystem01 { public void receiveLetters() { System.out.println("邮局接收用户的信件..."); } }
// 子系统02,邮局检查信件并分类的业务 class Subsystem02 { public void checkLetters() { System.out.println("邮局检查用户的信件..."); } }
// 子系统03,邮局让邮递员送信给收信人 class Subsystem03 { public void sendToReceiver() { System.out.println("邮递员送信 ..."); } }
// 子系统04,邮局新推出的赠送贺卡的特殊业务 class Subsystem04 { public void sendGreetingCard() { System.out.println("邮局的额外送贺卡服务 ..."); } }
// Facade01 ,只是普通的送信 class Facade01 { private Subsystem01 subsystem01; private Subsystem02 subsystem02; private Subsystem03 subsystem03; public Facade01() { this.subsystem01 = new Subsystem01(); this.subsystem02 = new Subsystem02(); this.subsystem03 = new Subsystem03(); } // 普通的送信,委托给各个必要的子系统 public void commonSendLetters() { this.subsystem01.receiveLetters(); this.subsystem02.checkLetters(); this.subsystem03.sendToReceiver(); } }
//Facade02 ,增加了送贺卡的业务 class Facade02 { // 委托 Facade01 进行普通业务的处理 private Facade01 facade01; private Subsystem04 subsystem04; public Facade02() { this.facade01 = new Facade01(); this.subsystem04 = new Subsystem04(); } // 特殊的送信 public void specialSendLetters() { this.facade01.commonSendLetters(); // 普通的送信之后再赠送贺卡 this.subsystem04.sendGreetingCard(); } }
// 测试类,即客户寄信 public class Client { public static void main(String[] args) { Facade01 facade01 = new Facade01(); facade01.commonSendLetters(); System.out.println(); Facade02 facade02 = new Facade02(); facade02.specialSendLetters(); } }
运行结果
邮局接收用户的信件... 邮局检查用户的信件... 邮递员送信 ... 邮局接收用户的信件... 邮局检查用户的信件... 邮递员送信 ... 邮局的额外送贺卡服务 ...
门面模式的优点:
减少系统的相互依赖:想不使用门面模式,外界访问直接深入到子系统内部,相互之间是一种强耦合关系,这样的强依赖是系统设计所不能接受的,门面模式的出现就很好地解决了该问题,所有的依赖都是对门面对象的依赖,与子系统无关。
提高了灵活性:依赖减少了,灵活性自然提高了。不管子系统内部如何变化,只要不影响到门面对象,任你自由活动。
提高安全性:想让你访问子系统的哪些业务就开通哪些逻辑,不在门面上开通的方怯,你休想访问到。
门面模式的缺点:
门面模式最大的缺点就是不符合开闭原则。修改发生时只能修改门面角色的代码。
门面模式的适用场景:
为一个复杂的模块或子系统提供一个供外界访问的接口。
子系统相对独立,外界对子系统的访问只要黑箱操作即可。
预防低水平人员带来的风险扩散
注意事项:
一般情况下,一个子系统只要有一个门面足够了,在什么情况下一个子系统有多个门面呢?门面已经庞大到不能忍受的程度,子系统可以提供不同访问路径。
Facade模式与 Mediator模式(中介者)的比较:
在 Facade 模式中,Facade 并不参与 Subsystem 类中的业务逻辑,所有的业务功能实际上全由各个 Subsystem 完成, Facade 只是在客户与 Subsystem 之间存在的一道门,客户只能拿着这道门的钥匙来获得业务功能、服务;而在 Mediator模式中,Mediator类是一个调停者、中介者,它完完全全地负责协调各个 Colleague 同事类之间的信息交互,以此来完成其工作。