设计模式学习之外观模式

385 阅读3分钟

UML结构类图的常用画法

简单工厂

Demo传送门

案例:有ModuleA,ModuleB,ModuleC三个类,这三个类实现三个不同的方法 1.按照普通思路,客户端如果想要和这三个类打交道,一般的做法就是直接引入三个类,分别进行实例化,然后引用三个类中的方法 2.采用外观模式,客户端无需知道这三个类的存在,只需要和外观层进行交互即可

下面先讲解一下采用普通方法的实现

1.定义接口

为了更加深刻的体会面向协议编程,我这里采用的都是协议方式,上述三者是定义了A,B,C三者的协议(用协议的好处是面向对象,后续增加新的协议方法比较方便集中管理)

2.实现协议

3.客户端调用

我们可以看到,用普通方法进行实现的时候,客户端必须要知道每一个类(即引入所有的头文件),如此一来客户端和各个实现类的关系耦合度就太大了,不利于扩展修改,同时也不满足接口隔离的原则,如果实现类新增或者改变了,客户端也要做相应的改变。 那么如果想要隔离客户端与各个子模块实现类的交互该怎么办呢?

外观模式就很好地解决了这个难题,下面从一张UML图来看外观模式:

客户端从始至终只需要和Facade进行打交道

外观模式实现

接口定制和子模块的具体实现前面已经有了,这里只需要看下外观类和客户端调用即可

外观类实现

我们看到普通方法中的客户端调用的实现到了这里来了

客户端调用

客户端调用更加清爽了

下面详细讲述一下什么是外观模式。 相信看到这里,我们也能大致推测出,外观模式无非就是一层外衣,包裹住里面的子模块,客户端接触的只有这一层外衣,具体里面是什么,实现了什么,完全不用管,子模块和客户端的解耦也是很彻底的.

外观模式不是为了给子模块添加新的功能接口,而是让外部与内部子模块的耦合度降低,它只是用来包装已有的功能,负责组合已有功能来实现客户端的需要,说白了就是我有N多个功能模块,现在我有一个需求需要实现这些模块中的某几个,那就可以用外观来包一下供给外界使用。

前面也可以看到外观模式无非就是把客户端代码搬到了外观类中,由外观类包装,客户端调用,然而本质上是有变化的。外观类所在层面不是客户端,而是系统(组件),它屏蔽了客户端和内部模块的交互,将各个子模块组合成为一个整体,封装了内部具体的实现细节,方便了外界的调用。此外,外观模式的功能还可以被多个客户端调用,如果有N个客户端实现的功能模块一样,直接调用外观类即可,这样就实现了很好地复用,外观模式的本质就是,封装交互,简化调用,体现了最少知识原则

下面说一下外观模式的优缺点:

优点

  • 松耦合
  • 简单易用
  • 更好地划分访问层次

缺点

  • 过多的或者不合理的facade容易让人迷惑