《Java Design Patterns》第十一章 外观模式

第十一章 外观模式

一、外观模式

在日常开发中,注册一个用户需要进行如下操作:验证手机验证码、生成用户类、存储至数据库、初始化用户积分等等操作。但是 客户端只需要调用一个 UserService.register() 即可,具体的其他对象的操作都交给 UserService 的实现来完成。

还有如 MVC 模式中,Controller 层中通过调用 service 来解耦 Controller 层与 Dao 层,隔离各个层次,实现层次化结构。

于 controller 而言,service 就是外观类,由service 来处理多个dao的交互。

1.1 定义

外观模式,又称为门面模式,是一种使用频率非常高的结构型设计模式,通过引入一个外观对象来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。

外观模式是迪米特法则的一种具体实现,通过引入一个新的外观角色可以降低原油系统的复杂度,同时降低客户类与子系统的耦合。

1.2 外观模式

外观模式示意图

在日常生活中,自己泡茶和去茶馆喝茶的区别类似于上图显示的这样。自己泡需要与 热水、差距、茶叶 进行交互(系统耦合度十分的高),而去茶馆喝茶只需要与服务员(Facade)进行交互即可。

1.3 外观模式中的几个角色:

  1. Facade - 外观角色
    1. 由客户端调用其中的方法,来访问相关子系统的功能
    2. 由外观角色将客户端的请求委派到具体子系统中
  2. SubSystem - 子系统角色
    1. 系统中可以存在一个或多个子系统角色
    2. 每个可以被客户端调用,也可以被外观角色调用,用于处理请求
    3. 子系统并不知道外观的存在,与它而言,外观角色仅仅是另一个客户端

二、完整实现

/**
 * 外观模式
 */
class SubSystemA {
    public void sayHello() {
        System.out.println("大家好,我是系统A");
    }
}

class SubSystemB {
    public void byebye() {
        System.out.println("再见,我是系统B");
    }
}

class SubSystemC {
    public void o() {
        System.out.println("i don't wanna see you anymore.");
    }
}

class Facade {
    private SubSystemA a = new SubSystemA();
    private SubSystemB b = new SubSystemB();
    private SubSystemC c = new SubSystemC();

    public void bb(){
        a.sayHello();
        c.o();
        b.byebye();
    }
}

public class FacadePattern {
    public static void main(String[] args) {
        // 通过外观类 Facade 减少了客户端与各个子系统的直接交互,降低耦合度
        final Facade facade = new Facade();
        facade.bb();
    }
}

三、抽象外观类

在标准外观模式中,如果需要增加、删除或更换与外观类交互的子系统类,必须修改外观类或客户端的代码。这将违背开闭原则。

可以引入抽象外观类来对系统进行改进,客户端针对抽象外观类进行编程。

四、总结

优点

  1. 对客户端屏蔽子系统组件,减少客户端所需处理的对象数目,使子系统的使用更加容易
  2. 客户端与子系统间关联的对象会减少
  3. 实现了子系统和客户端之间的松耦合,子系统的变化只需要调整外观类即可
  4. 子系统的修改不会影响其他子系统,且子系统内部修改不会影响到外观类

缺点

  1. 由外观类来调用子系统类,减少了客户端直接调用时的灵活性和可变性
  2. 如果设计不当,增加子系统时可能会修改外观类,违背了开闭原则

适用场景

  1. 当需要为访问一系列复杂的子系统对象提供简单入口时,可以使用外观模式
  2. 外观类可以将子系统与客户端解耦,从而提高子系统的独立性和可移植性
  3. 在层次化结构中,可以使用外观模式定义系统中的每一层入口。层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度
文章作者: koral
文章链接: http://luokaiii.github.io/2019/07/11/读书笔记/《JavaDesignPatterns》/13.外观模式/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自