设计模式-外观模式

103 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

模式意图

将一个复杂的子系统向外提供一个一致的接口,外部应用程序想要调用子系统的各个方法时,不再需要关注子系统的复杂结构,也就是不需要再思考调用子系统的哪些方法,通过调用接口的某一个方法就能实现子系统功能。

模式结构

  • 外观角色:为多个子系统提供一个共同接口
  • 子系统角色:实现系统的部分功能,客户通过外观角色来进行访问

智能家电案例

​编辑

电灯,空调,电视是子系统类,如果爷爷想打开这些电器,需要挨个去打开,如果有了外观类智能语音识别设备,爷爷只需要对智能设备说打开,就可以实现打开所有的电器。

该模式只简单的在外观类中将所有子系统类进行了聚合

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对象