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 (简单)

image.png

  1. public class Main {
  2. public static void main(String[] args) {
  3. Facade facade = new Facade();
  4. facade.MethodA();
  5. facade.MethodB();
  6. }
  7. }
  8. class SubSystemOne {
  9. public void MethodOne() {
  10. System.out.println("子系统方法一");
  11. }
  12. }
  13. class SubSystemTwo {
  14. public void MethodTwo() {
  15. System.out.println("子系统方法二");
  16. }
  17. }
  18. class SubSystemThree {
  19. public void MethodThree() {
  20. System.out.println("子系统方法三");
  21. }
  22. }
  23. class SubSystemFour {
  24. public void MethodFour() {
  25. System.out.println("子系统方法四");
  26. }
  27. }
  28. class Facade {
  29. SubSystemOne one;
  30. SubSystemTwo two;
  31. SubSystemThree three;
  32. SubSystemFour four;
  33. public Facade() {
  34. one = new SubSystemOne();
  35. two = new SubSystemTwo();
  36. three = new SubSystemThree();
  37. four = new SubSystemFour();
  38. }
  39. public void MethodA() {
  40. System.out.println("方法组A");
  41. one.MethodOne();
  42. two.MethodTwo();
  43. four.MethodFour();
  44. }
  45. public void MethodB() {
  46. System.out.println("方法组B");
  47. two.MethodTwo();
  48. three.MethodThree();
  49. }
  50. }

4、总结

4.1、优缺点

1)优点

2)缺点

  • 增加子系统,需要修改门面类,容易引入风险。
  • 修改门面类,不符合开闭原则

    4.2、门面模式与代理模式的区别

    在了解门面模式时,会发现它不仅与代理模式很像,与装饰器模式也很类似;
    它们之间到底有什么样的区别呢?

相似点:
- 都引入了中介类(对象)
- 中介对象都引用并把功能委托给了原对象
- 都起到了”代理”功能

区别
- 代理侧重于对原对象的访问控制(当然也可以不是控制而是功能增强)
- 代理与原类实现相同的抽象(相同接口或直接继承原业)
- 代理只代理一个类
- 门面侧重于功能整合(多个小系统或小对象整合成一个功能丰富的大对象)
- 门面可以与子系统具有不同的抽象(具有不同的接口,可以对方法重新起名)
- 门面代理的是一系列类

4.3、何时使用门面模式

首先,在设计初期阶段,应该要有意识的 将不同的两个层分离, 比如经典的三层架构,就需要考虑在数据访问 层和业务逻辑层、业务逻辑层和表示层的层与层之间建立外观 Facade ,这样可以为复杂的子系统提供一个简单的接口,使得耦合大 大降低。

其次,在开发阶段,子系统往往因为不断的重构演化而变得 越来越复杂, 大多数的模式使用时也都会产生很多很小的类,这本是 好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观 Facade 可以提供一个简单的接口,减少它们之间的依赖。

第三,在维 护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展 了, 但因为它包含非常重要的功能,新的需求开发必须要依赖于它。 此时用外观模式Facade也是非常合适的。你可以为新系统开发一个外观 Facade 类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的 接口,让新系统与 Facade 对象交互, Facade 与遗留代码交互所有复杂 的工作。
image.png

4.2、关于门面模式的一些问题

待续