常用设计模式 -- 一分钟就能学会的门面模式(外观模式)
上次在整理日志框架的时候,发现里面用到了一个设计模式----门面模式(外观模式),找了一些资料去了解,其实非常简单,我们在开发的时候可能还经常不经意间去使用过,在这里写一下总结。
【提示】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
定义
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
UML图
从 UML图可以看出,客户端调用的时候只需要与门面类 Facade 进行交互,并不需要知道子系统的存在,而 Facade 类则需要知道全部子系统的功能,进行具体调用。
四个子系统类
class SubSystemOne {
public void MethodOne() {
System.out.println("子系统方法一");
}
}
class SubSystemTwo {
public void MethodTwo() {
System.out.println("子系统方法二");
}
}
class SubSystemThree {
public void MethodThree() {
System.out.println("子系统方法三");
}
}
class SubSystemFour {
public void MethodFour() {
System.out.println("子系统方法四");
}
}
外观类
class Facade {
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
SubSystemFour four;
public Facade() {
one = new SubSystemOne;
two = new SubSystemTwo;
three = new SubSystemThree;
four = new SubSystemFour;
}
public void MethodA() {
System.out.println("方法组A() ---- ");
one.MethodOne();
two.MethodTwo();
four.MethodFour();
}
public void MethodB() {
System.out.println("方法组B() ---- ");
two.MethodTwo();
three.MethodThree();
}
}
客户端调用
public static void main(String[] args) {
Facade facade = new Facade();
//由于 Facade 的作用,客户端不需要知道子系统类的存在,只要由Facade调用就行
facade.MathodA();
facade.MathodB();
}
以上代码就是一个门面模式了。
有一定面向对象基础的朋友就会说,这不就是多加了一层封装吗?
没错,就是多加了一层封装而已,所以即使我们之前没听过外观模式,也在不经意间使用过它。
优缺点
优点: 它完美地体现了依赖倒转原则和迪米特法则的思想,是非常常用的设计模式之一。
缺点: 不符合开闭原则,对修改关闭,对扩展开放。如果我们想多加一个子系统,那就只能在门面对象上修改代码;
使用场景:
- 在设计初期阶段,有意识的将不同的两个层分离。比如经典的 MVC 架构,就要考虑持久层和业务层、业务层和控制层的层与层之间建立外观 Facade,使得耦合大大降低。
- 在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂。这时增加外观 Facade 可以提供一个简单的接口,减少它们之间的依赖。
- 在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但它包含非常重要的功能,新的需要开发需要依赖它。这时可以为新系统开发一个外观 Facade 类,让新系统与 Facade 对象交互,Facade 与遗留代码交互所有复杂的工作。