13 外观模式
13.1 外观模式概述
Facade Pattern: 为子系统的接口提供一组统一的入口。外观模式定义了一个高层接口,这个接口使得子系统的更加容易使用。
在外观模式中,一个子系统的外部与其内部通信通过一个统一的外观类进行,外观类将客户类与子系统的内部复杂性分隔,使得客户类只需要与外观角色打交道,而不需要与子系统内部的很多其他对象交互。
外观模式是迪米特法则的一种具体实现,通过引入一个外观角色降低原有系统的复杂度,同时降低客户类与子系统的耦合度。
此处复习一下迪米特法则的内容描述:
迪米特法则: 每一个软件单元对其他单元都只有最少的信息,而且局限于那些与本单元密切相关的软件单元。迪米特法则要求一个软件实体应该尽可能少地与其他实体发生相互作用。
外观模式结构图如下所示:
13.2 外观模式实现
13.2.1 外观类
客户端调用外观类的方法,外观类将客户端请求委派给相应的子系统处理。
public class Facade {
private SubSystemA subA = new SubSystemA();
private SubSystemB subB = new SubSystemB();
private SubSystemC subC = new SubSystemC();
public void method(String s) {
String resA = subA.methodA(s);
String resB = subB.methodB(resA);
subC.methodC(resB);
}
}
13.2.2 子系统类
子系统处理外观类传过来的请求;子系统并不知道外观类的存在,外观类仅仅是封装了多个请求的一个客户端。
public class SubSystemA() {
public String methodA(String s) {
// 业务逻辑代码
}
}
public class SubSystemB() {
public String methodB(String s) {
// 业务逻辑代码
}
}
public class SubSystemC() {
public void methodA(String s) {
// 业务逻辑代码
}
}
13.2.3 客户端调用
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.method();
}
}
13.3 抽象外观类
在上述外观模式中,如果需要增加或删除与外观类交互的子系统类,必须修改原有代码,违背开闭原则,因此可以通过引入抽象外观类对系统进行改进。
引入抽象外观类的外观模式结构图如下所示:
引入抽象外观类之后,客户端可以针对抽象层编程,对于新的业务需求,不需要修改原有的外观类,直接增加一个新的具体外观类即可,符合开闭原则。
13.4 外观模式优/缺点
外观模式使用场景:菜单栏或工具栏
外观模式的优点主要如下:
- 对客户端屏蔽子系统组件,将客户端代码简化,与之关联的对象也减少
- 实现了子系统与客户端之间的松耦合关系,使得子系统发生变化,无须修改客户端,只调整外观类即可
外观模式的缺点主要如下:
- 不能很好的限制客户端直接使用子系统类,子系统类对客户端是可见的,不好限制客户端只能去调用外观类;
- 设计不当会导致增加新的业务逻辑需要修改原有代码(未引入抽象外观类)