外观模式(Facade):又称门面模式,是指为子系统中的一组接口提供一个一致的界面,门面模式提供一个高层接口,使得子系统更加容易使用。其中门面相当于子系统的客户端,而真正的客户端使用者只需要和门面打交道,松散客户端与子系统之间的耦合关系,使程序更易维护扩展。
举个例子,现在有个安保系统。
- 一般写法就是工作人员(客户端)直接去控制一些安保工具的使用
//安保系统的监视器
public interface Monitor {
void monitor();
}
//外部监视器
public class OutsideMonitor implements Monitor {
@Override
public void monitor() {
System.out.println("外部监视器启动...");
}
}
//内部监视器
public class InsideMonitor implements Monitor {
@Override
public void monitor() {
System.out.println("内部监视器启动...");
}
}
//外部探照灯
public class SearchLight {
public void light(){
System.out.println("探照灯启动...");
}
}
//红外线探测
public class InfraredRay {
public void turnOn(){
System.out.println("红外线探测启动...");
}
}
public class Main {
public static void main(String[] args) {
//手动开启外部监视器
OutsideMonitor outMonitor = new OutsideMonitor();
outMonitor.monitor();
//手动开启内部监视器
InsideMonitor inMonitor = new InsideMonitor();
inMonitor.monitor();
//手动开启探照灯
SearchLight light = new SearchLight();
light.light();
//手动开启红外线
InfraredRay ray = new InfraredRay();
ray.turnOn();
/**
* console:
* 外部监视器启动...
* 内部监视器启动...
* 探照灯启动...
* 红外线探测启动...
*/
}
}
这样客户端直接调用安保系统,与各个安保工具(子系统)之间的耦合变得紧密,客户端需要了解每个安保工具的具体内部逻辑实现,才可以准确使用,并且当子系统出现变动时,客户端代码可能也会随之而变。
- 使用外观模式,增加一个中央控制器控制安保系统,客户端只要操作控制器即可完成
//中央控制器,安保系统的门面
public class CentralControlFacade {
//一级预案
public void firstPlan(){
System.out.println("启动一级预案...");
//控制器开启外部监视器
OutsideMonitor outMonitor = new OutsideMonitor();
outMonitor.monitor();
//控制器开启内部监视器
InsideMonitor inMonitor = new InsideMonitor();
inMonitor.monitor();
//控制器开启探照灯
SearchLight light = new SearchLight();
light.light();
//控制器开启红外线
InfraredRay ray = new InfraredRay();
ray.turnOn();
}
//二级预案
public void secondPlan(){
System.out.println("启动二级预案...");
OutsideMonitor outMonitor = new OutsideMonitor();
outMonitor.monitor();
SearchLight light = new SearchLight();
light.light();
}
}
public class Main {
public static void main(String[] args) {
CentralControlFacade facade = new CentralControlFacade();
//二级预案
facade.secondPlan();
//一级预案
facade.firstPlan();
/**
* console:
* 启动二级预案...
* 外部监视器启动...
* 探照灯启动...
*
* 启动一级预案...
* 外部监视器启动...
* 内部监视器启动...
* 探照灯启动...
* 红外线探测启动...
*/
}
}
这样客户端使用中央控制器(门面),与具体的安保工具(子系统)的耦合变得松散,客户端既不需要直接了解具体安保的实现逻辑,这部分交由门面来控制,客户端的代码相对变得简单,也不会因为子系统代码的变动而变动。
门面模式有着很好的封装思想,当业务复杂时,可以理清业务层次封装出多个门面出来,形成集中统一又相对简化的接口供客户端调用,又或者需要封装内部算法,避免被胡乱修改,也可以使用门面模式。