背景
最近公司的一个同事要离职了,然后老大让我来接手他的工作。看了一段时候他工作的业务文档后,就慢慢开始摸索他的代码了,然后发现了在代码层面上使用大量的Facade类,然后围绕着Facade给外部提供了各种各种的方法,于是很好奇就问他这个Facade到底是用来干嘛的,为什么要弄这个呢,然后它告诉我说这个叫门面设计模式,也叫做外观模式,由于现在的子系统越来越多越来越复杂,采用门面模式也可以尽量的对系统模块进行隔离,提供各个功能之间的独立性,另外一个就是使用起来很简单。
概述
门面模式又叫作外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构型设计模式(摘自百科)。
在我们生活中,其实有很多的类似于门面模式的例子。比如我们建房子,如果没有包工头的话,那就是你自己要去找水泥工,电工、装修工等。但如果有了包工头,这些活你都不用干了,直接跟包工头说,需要电工来把线路搞好。这个包工头就可以理解为门面模式。
再比如,我们在医院都会有这么一个接待员的角色,由接待员负责代为挂号、划价、缴费、取药等。这个接待员就是门面模式的体现,病人只接触接待员,由接待员与各个部门打交道。我们在来看一下它的类图,以及代码实现。
由上图可以看到,门面模式主要包含2个角色:1,外观角色(Facade):也叫作门面角色,是系统对外的统一接口。2,子系统角色(Service):可以同时有一个或多个Service。每个Service都不是一个单独的类,而是一个类的集合。Service们并不知道Facade的存在,对于Service们而言,Facade 只是另一个客户端而已(即Facade对ServiceA、ServiceB、ServiceC透明)。
子系统角色-实现类:
1 public class ServiceA {
2 public void doA(){
3 System.out.println("I'm ServiceA...");
4 }
5 }
6
7
8
9 public class ServiceB {
10 public void doB(){
11 System.out.println("I'm ServiceB...");
12 }
13 }
14
15
16
17
18 public class ServiceC {
19 public void doC(){
20 System.out.println("I'm ServiceC...");
21 }
22 }
接下来是门面角色(facade):包工头
1 //包工头
2 public class Facade {
3 private ServiceA serviceA;
4 private ServiceB serviceB;
5 private ServiceC serviceC;
6
7 public void Facade(){
8 serviceA = new ServiceA;
9 serviceA = new ServiceB;
10 serviceC = new ServiceC:
11 }
12
13 //满足客户端的功能
14 public void doA() {
15 serviceA.doA();
16 }
17
18 public void doB() {
19 serviceB.doB();
20 }
21
22 public void doC() {
23 serviceC.doC();
24 }
25 }
最后呢就是客户端类
1 //客户端
2 public class Client {
3 public static void main(String[] args) {
4 Facade facade = new Facade();
5 facade.doA();
6 facade.doB();
7 facade.doC();
8 facade.getDrug();
9 }
10 }
这么一看,用代码和类图比较一下你会发现,其实他和代理模式有异曲同工之妙,都同时引入了第三者中介,其实还是有很大的区别的。虽然说这个中介起到了代理的功能。但是代理模式只代理一个类,而且代理类与原类实现相同的抽象。门面类就不一样了,他代理的是一系列类,与子系统可以有不同的抽象。
门店模式特点:1、能够有选择性地暴露方法。一个模块中定义的方法可以分成两部分,一部分是给子系统外部使用的,一部分是子系统内部模块之间相互调用时使用的。有了Facade类,那么用于子系统内部模块之间相互调用的方法就不用暴露给子系统外部了2、在门面模式中,通常只需要一个门面类。如果一个系统有好几个子系统的话,每一个子系统都有一个门面类,整个系统可以有数个门面类。3、门面模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为。就比如包工头的作用只是调度其他人工作的,但是自己不工作。4、用户与子系统解耦,屏蔽子系统;可以提高子系统的独立性;并且客户类不需要知道子系统的内部构造。但是呢,他也有一个缺点,就是在有的时候可能会违背单一职责原则。