外观模式

定义:

提供了一个统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,让子系统更容易使用。

设计类图:
外观模式_第1张图片
外观模式又叫做门面模式,看上去是一个比较宏观的模式,它包含的两个主要角色:

  • Facade(外观)角色:提供一个外观接口,对外,它提供一个易于客户端访问的接口,对内,它可以访问子系统中的所有功能。
  • SubSystem(子系统)角色:子系统在整个系统中可以是一个或多个模块,每个模块都有若干类组成,这些类可能相互之间有着比较复杂的关系。

示例代码:

public class ClassA {
    private ClassB classB;

    public void methodA() {
        methodA2();
    }

    public void methodA2() {
        classB.methodB();
    }
}
public class ClassB {

    public void methodB() {
    }

    public void methodB2(ClassC classC) {
        classC.methodC();
    }
}
public class ClassC {
    public void methodC() {
    }
}
public class Facade {

    public void test() {
        ClassA classA = new ClassA();
        ClassB classB = new ClassB();
        ClassC classC = new ClassC();
        classA.methodA();
        classB.methodB();
        classC.methodC();
    }
}
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.test();
    }
}

  上述代码中ClassA、ClassB、ClassC是系统中某个模块的三个类,它们之间可以有复杂的依赖关系,但是Facade对象负责将三个类的调用方法包装起来,对外在Client类看来,它好像只有一个方法。对于客户端来讲,简化了接口的调用,原来需要依赖三个类并调用三个类的方法,现在只需要一个。

外观模式_第2张图片

  如上图所示,外观模式将原来客户端与子系统中各个类的复杂交互统一了起来,交由Facade角色去处理,简化了操作流程,对客户端来说接口的调用变得简单了许多,客户端只与最直接的Facade角色进行交流,再也无需关心子系统内部的复杂结构,达到了解耦的目的。

医院的例子

  如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系统的各个类打交道一样,不是一件容易的事情。

  首先病人必须先挂号,然后门诊。如果医生要求化验,病人必须首先划价,然后缴费,才可以到化验部门做化验。化验后再回到门诊室。
外观模式_第3张图片
  引入外观模式可以很好的解决这个问题,医院可以设置一个接待员的位置,由接待员负责代为挂号、划价、缴费、取药等。这个接待员就是外观模式中Facade角色的体现,病人只接触接待员,由接待员与各个部门打交道。
外观模式_第4张图片
  值得一提的是,在一个系统中外观角色可能不止一个,如果有需要,你可以为子系统提供一个以上的外观角色,每个外观角色的侧重点也可以不一样。

外观模式的优点

  外观模式最大的优点就是使复杂子系统的接口变的简单可用,减少了客户端对子系统的依赖,达到了解耦的效果,这也是外观模式设计的目的所在。同时外观模式遵循了OO原则中的迪米特法则,对内封装具体细节,对外只暴露必要的接口。

使用场景

  • 为一个复杂的模块或子系统提供一个供外界访问的接口
  • 子系统相对独立 ― 外界对子系统的访问只要黑箱操作即可
  • 防止代码修改带来的风险扩散,控制风险范围



参考:

  • 《设计模式之禅》
  • 《Head First设计模式》
  • 《Java与模式》

你可能感兴趣的:(架构设计,设计模式,外观模式,门面模式,设计模式)