本文已参与「新人创作礼」活动,一起开启掘金创作之路。
模式意图
将一个复杂的子系统向外提供一个一致的接口,外部应用程序想要调用子系统的各个方法时,不再需要关注子系统的复杂结构,也就是不需要再思考调用子系统的哪些方法,通过调用接口的某一个方法就能实现子系统功能。
模式结构
- 外观角色:为多个子系统提供一个共同接口
- 子系统角色:实现系统的部分功能,客户通过外观角色来进行访问
智能家电案例
编辑
电灯,空调,电视是子系统类,如果爷爷想打开这些电器,需要挨个去打开,如果有了外观类智能语音识别设备,爷爷只需要对智能设备说打开,就可以实现打开所有的电器。
该模式只简单的在外观类中将所有子系统类进行了聚合
package mode; public class Client{ public static void main(String[] args) { SmartAppliancesFacade saf = new SmartAppliancesFacade(); saf.say("帮我打开电视不咋"); } } //子系统角色 class Light{ public void on(){ System.out.println("开灯"); } public void off(){ System.out.println("关灯"); } } //子系统角色 class TV{ public void on(){ System.out.println("打开电视机"); } public void off(){ System.out.println("关闭电视机"); } } //子系统角色 class AirCondition{ public void on(){ System.out.println("打开空调"); } public void off(){ System.out.println("关闭空调"); } } //外观类 class SmartAppliancesFacade{ //聚合电灯对象,电视对象,空调对象 private Light light; private TV tv; private AirCondition airCondition; public SmartAppliancesFacade() { light = new Light(); tv = new TV(); airCondition = new AirCondition(); } //通过语音控制 public void say(String message){ if(message.contains("打开")){ on(); }else if(message.contains("关闭")){ off(); }else { System.out.println("请您再说一遍"); } } //一键打开功能 private void on(){ light.on(); tv.on(); airCondition.on(); } //一键关闭方法 private void off(){ light.off(); tv.off(); airCondition.off(); } }
优点
- 降低子系统与客户之间耦合度
- 对客户屏蔽了子系统组件,减少客户处理的对象数目,使子系统用起来更容易,外观模式通过为子系统设计一个接口,本来需要调用子系统的很多方法,通过外观模式只需调用一个方法就代替了调用多个方法。
- 外观模式还可以保护子系统,并且外观模式中的成员属性不能直接访问。
缺点
不符合开闭原则,修改很麻烦
使用场景
- 当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问
- 客户端与多个子系统存在联系时,引用外观模式可将它们分离,将各个部分子系统实现不同外观接口
源码解析
编辑
编辑
Request被外观模式聚合后可以保护Request对象