1. 概念
外观模式的主要目的在于让外部减少与子系统内部多个模块的交互,从而让外部能够更简单的使用子系统,它负责把客户端的请求转发给子系统内部的各个模块进行处理。
外观模式提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用。
2. 使用场景
- 如果你希望为复杂的子系统提供一个简单接口的时候,可以考虑使用外观模式。使用外观对象对实现大部分客户需要的功能,从而简化客户的使用。
- 如果想要让客户程序和抽象类的实现部分松散耦合,可以考虑使用外观模式,使用外观对象来将这个子系统与它的客户分离开来,从而提高子系统的独立性和可移植性。
- 如果构建多层结构的系统,可以考虑使用外观模式,使用外观对象作为每层的入口,这样就可以简化层间调用,也可以松散层次之间的依赖关系。
3. 实例
外观模式有两个角色:
- Facade 角色:系统对外的统一接口,客户端连接子系统功能的入口。
- 子系统角色(SubSystem)角色:可以同时有一个或者多个子系统,每个子系统都不是一个单独的类,而是一个类的集合。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
子系统:
public class SystemA {
public void operation1(){
System.out.print("SystemA:operation1\n");
}
public void operation2(){
System.out.print("SystemA:operation2\n");
}
public void operation3(){
System.out.print("SystemA:operation3\n");
}
}
public class SystemB {
public void operation1(){
System.out.print("SystemB:operation1\n");
}
public void operation2(){
System.out.print("SystemB:operation2\n");
}
public void operation3(){
System.out.print("SystemB:operation3\n");
}
}
public class SystemC {
public void operation1(){
System.out.print("SystemC:operation1\n");
}
public void operation2(){
System.out.print("SystemC:operation2\n");
}
public void operation3(){
System.out.print("SystemC:operation3\n");
}
}
然后是外观对象 IFacade.class
public interface IFacade {
void operationA();
void operationB();
void operationC();
}
Facade.class
public class Facade implements IFacade{
private SystemA systemA = new SystemA();
private SystemB systemB = new SystemB();
private SystemC systemC = new SystemC();
@Override
public void operationA() {
systemA.operation1();
systemB.operation2();
systemC.operation3();
}
@Override
public void operationB() {
systemA.operation2();
systemB.operation1();
systemC.operation3();
}
@Override
public void operationC() {
systemC.operation1();
systemB.operation2();
systemA.operation3();
}
}
最后的测试代码:
public static void main(String args[]) {
IFacade facade = new Facade();
facade.operationA();
facade.operationB();
facade.operationC();
}
4. 优点
- 由于Facade类封装了各个模块的交互过程,如果今后内部模块调用关系发生了变化,只需要修改Facade实现就可以了
- Facade是可以被多个客户端调用的松散耦合
- 简单易用
- 更好的划分访问的层次
5. 缺点
- 过多的或者是不太合理的Facade也容易让人迷惑。到底是调用Facade好还是直接调用模块好。