基本概念
外观模式(Facade Pattern) 为所有子系统提供一个统一的管理的接口,屏蔽了子系统的实现细节,用户端直接调用统一的接口避免了客户端直接跟各个子系统直接交互使得客户端调用更加清晰简单。
外观模式类似一个总控器,里面包含了许多子系统的各种功能。比如智能家居,外观模式封装另一个能控制各种家居的遥控器,比如你要看电视,你只需要调用外观类的watchTV方法,在外观类的内部会调用TV的open,窗帘Close,音响的open。客户端调用了一个方法本质上底层调用了3个不同子系统的相关方法。
UML
外观类组合了所有子系统,客户端直接调用Facade的暴露的方法就好
- 外观类(Facade) 对外暴露的统一接口
- 调用者(Client): 外观接口的调用者
- 子系统(SubSystem): 各个子系统
代码实现
//子系统角色
public class TV {
public void open() {
System.out.println("TV is open");
}
public void close() {
System.out.println("TV is close");
}
private static class InstanceHolder {
private static TV INSTANCE = new TV();
}
public static TV getInstance() {
return TV.InstanceHolder.INSTANCE;
}
}
public class Stereo {
public void open() {
System.out.println("Stereo is open");
}
public void close() {
System.out.println("Stereo is close");
}
private static class InstanceHolder {
private static Stereo INSTANCE = new Stereo();
}
public static Stereo getInstance() {
return Stereo.InstanceHolder.INSTANCE;
}
}
public class Curtain {
public void up() {
System.out.println("Curtain is up");
}
public void down() {
System.out.println("Curtain is down");
}
private static class InstanceHolder {
private static Curtain INSTANCE = new Curtain();
}
public static Curtain getInstance() {
return InstanceHolder.INSTANCE;
}
}
// 外观类
public class Facade {
private TV tv;
private Stereo stereo;
private Curtain curtain;
public Facade() {
this.tv = TV.getInstance();
this.stereo = Stereo.getInstance();
this.curtain = Curtain.getInstance();
}
public void watchTV() {
tv.open();
stereo.open();
curtain.up();
}
public void closeTV() {
tv.close();
stereo.close();
curtain.down();
}
}
// 客户端
public class FacadeTest {
public static void main(String[] args) {
Facade facade = new Facade();
facade.watchTV();
System.out.println("===========================================");
facade.closeTV();
}
}
使用细节
外观模式屏蔽子系统调用细节,客户端无需关心子系统的调用过程
子系统模块独立维护,增加扩展性
适用于包装内部复杂逻辑调用,对外暴露一个简单的调用模式。比如一个老系统里面功能已经非常复杂,而且有一些功能已经废弃不用,但现有业务又需要依然老系统的一些功能,这种时候就可以封装一个外观接口出来,让调用端不需要关系老系统内部的细节。