1、什么是门面模式
门面模式,也叫外观模式,英文全称是 Facade Design Pattern。在 GoF 的《设计模式》一书中,门面模式是这样定义的:
Provide a unified interface to a set of interfaces in a subsystem. Facade Pattern defines a higher-level interface that makes the subsystem easier to use.
翻译成中文就是:门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。
适配器是做接口转换,解决的是原接口和目标接口不匹配的问题。
门面模式做接口整合,解决的是多接口调用带来的问题。
2、为什么要用门面模式
1、子系统越来越复杂,增加外观模式提供简单调用接口
2、构建多层系统结构,利用外观对象作为每层的入口,简化层间调用
为了保证接口的可复用性(或者叫通用性),我们需要将接口尽量设计得细粒度一点,职责单一一点。但是,如果接口的粒度过小,在接口的使用者开发一个业务功能时,就会导致需要调用 n 多细粒度的接口才能完成。调用者肯定会抱怨接口不好用。
相反,如果接口粒度设计得太大,一个接口返回 n 多数据,要做 n 多事情,就会导致接口不够通用、可复用性不好。接口不可复用,那针对不同的调用者的业务需求,我们就需要开发不同的接口来满足,这就会导致系统的接口无限膨胀。
那如何来解决接口的可复用性(通用性)和易用性之间的矛盾呢?通过今天对于门面模式的学习,我想你心中会有答案。
Spring ApplicationContext 它实现了 Factory 、 ResourceLoader 等接口,并通过引用这些接口的实例,对外统一提供:加载配置、解析资源、创建Bean、提供环境、启动流程等功能。
3、例子
3.1、GoF (简单)

public class Main {public static void main(String[] args) {Facade facade = new Facade();facade.MethodA();facade.MethodB();}}class SubSystemOne {public void MethodOne() {System.out.println("子系统方法一");}}class SubSystemTwo {public void MethodTwo() {System.out.println("子系统方法二");}}class SubSystemThree {public void MethodThree() {System.out.println("子系统方法三");}}class SubSystemFour {public void MethodFour() {System.out.println("子系统方法四");}}class Facade {SubSystemOne one;SubSystemTwo two;SubSystemThree three;SubSystemFour four;public Facade() {one = new SubSystemOne();two = new SubSystemTwo();three = new SubSystemThree();four = new SubSystemFour();}public void MethodA() {System.out.println("方法组A");one.MethodOne();two.MethodTwo();four.MethodFour();}public void MethodB() {System.out.println("方法组B");two.MethodTwo();three.MethodThree();}}
4、总结
4.1、优缺点
1)优点
2)缺点
- 增加子系统,需要修改门面类,容易引入风险。
- 修改门面类,不符合开闭原则
4.2、门面模式与代理模式的区别
在了解门面模式时,会发现它不仅与代理模式很像,与装饰器模式也很类似;
它们之间到底有什么样的区别呢?
相似点:
- 都引入了中介类(对象)
- 中介对象都引用并把功能委托给了原对象
- 都起到了”代理”功能
区别
- 代理侧重于对原对象的访问控制(当然也可以不是控制而是功能增强)
- 代理与原类实现相同的抽象(相同接口或直接继承原业)
- 代理只代理一个类
- 门面侧重于功能整合(多个小系统或小对象整合成一个功能丰富的大对象)
- 门面可以与子系统具有不同的抽象(具有不同的接口,可以对方法重新起名)
- 门面代理的是一系列类
4.3、何时使用门面模式
首先,在设计初期阶段,应该要有意识的 将不同的两个层分离, 比如经典的三层架构,就需要考虑在数据访问 层和业务逻辑层、业务逻辑层和表示层的层与层之间建立外观 Facade ,这样可以为复杂的子系统提供一个简单的接口,使得耦合大 大降低。
其次,在开发阶段,子系统往往因为不断的重构演化而变得 越来越复杂, 大多数的模式使用时也都会产生很多很小的类,这本是 好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观 Facade 可以提供一个简单的接口,减少它们之间的依赖。
第三,在维
护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展
了, 但因为它包含非常重要的功能,新的需求开发必须要依赖于它。
此时用外观模式Facade也是非常合适的。你可以为新系统开发一个外观
Facade 类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的
接口,让新系统与 Facade 对象交互, Facade 与遗留代码交互所有复杂
的工作。
4.2、关于门面模式的一些问题
待续
