概念
外观模式:为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式引入了一个新的外观类,它为多个业务类的调用提供了一个统一的入口。主要优点是对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数量。
举个例子,比如查询人员的权限,客户端可以调用外观类的方法,外观类中封装一个方法,方法里面依次调用两个实现类,该方法先是示查询出人员的角色,然后根据查出来的角色去查询角色的权限。将客户端与实现类进行解耦,就不用客户端调两次了,客户端只需要调用外观类一次即可。
结构
Facade(外观角色):外观角色中知道一个或多个子系统的功能和责任。它用来将客户端发来的请求委派到相应的子系统,传递给乡音的子系统对象处理。
SubSystem(子系统角色):系统中可以有一个或多个子系统角色,每一个子系统都可以被客户端直接调用,或者被外观角色调用。子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。
实例
比如我们上班回家后,要做的事情依次是开门、开灯、打开电视,现在用外观模式来完成这个过程。
Door 类
public class Door {
public void openDoor(){
System.out.println("门开了");
}
}
Lamp类
public class Lamp {
public void turnOnLight(){
System.out.println("灯开了");
}
}
TV类
public class TV {
public void turnOnTv() {
System.out.println("电视开了");
}
}
Facade类
public class Facade {
private TV tv = new TV();
private Door door = new Door();
private Lamp lamp = new Lamp();
public void open() {
tv.turnOnTv();
door.openDoor();
lamp.turnOnLight();
}
}
Client 端
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.open();
}
}
如果不用外观模式,则客户端的调用方式是这样的:
public class Client {
public static void main(String[] args) {
Door door = new Door();
Lamp lamp = new Lamp();
TV tv = new TV();
door.openDoor();
lamp.turnOnLight();
tv.turnOnTv();
}
}
上面是客户端直接调用业务实现类,需要依赖三个子系统,而使用外观模式,则只需要关联一个外观类,降低了系统的耦合度。
总结
优点:
1、它对客户端屏蔽了子系统,减少了客户端所需处理的对象数目,客户端代码变得很简单。
2、它实现了子系统和客户端的松耦合关系,使得子系统的变化不会影响到客户端,只需要更改外观类即可。
缺点:
1、违背开闭原则,有新的子系统加入需要修改外观类。
外观模式和建造者模式的思路很相似。外观模式是将复杂的子系统操作给外观类,客户端直接调用外观类即可;建造者模式是将复杂的操作给指挥者,指挥者内部指挥建造者创建,客户端直接关联指挥者即可。