由一名保安引发的Java设计模式:外观模式
阅读原文时间:2023年07月13日阅读:1

目录

应用场景

使用方要完成一个功能,需要调用提供方的多个接口、方法,调用过程复杂时,我们可以再提供一个高层接口(新的外观),将复杂的调用过程向使用方隐藏,适配器模式的变种

外观模式

隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口

为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用

降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口

  1. 客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可
  2. 定义系统的入口

优点:

  1. 减少系统相互依赖
  2. 提高灵活性
  3. 提高了安全性

缺点:

不符合开闭原则,如果要改东西很麻烦,继承重写都不合适

涉及到的角色:

  1. 门面(Facade)角色:客户端可以调用这个角色的方法。此角色知道相关的子系统的功能和责任,在正常情况下,此角色会将所有从客户端发来的请求委派到相应的子系统去
  2. 子系统(SubSystem)角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合;每一个子系统都可以被客户端直接调用,或者被门面角色调用,子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已

保安的故事

作为一名保安,需要熟悉保安系统,现在使用的保安系统有2个录像机,3个电灯、1个遥感器和1个报警器,保安系统的操作人员需要经常将这些仪器启动和关闭,首先,在不使用门面模式的情况下,这些部件都需要操作人员直接操作,下面写一个小例子:

操作人员类:

public class Client {

    static Camera camera1 = new Camera(), camera2 = new Camera();
    static Light light1 = new Light(), light2 = new Light(), light3 = new Light();
    static Sensor sensor = new Sensor();
    static Alarm alarm = new Alarm();

    public static void main(String[] args) {
        camera1.turnOn("1号录像机");
        camera2.turnOn("2号录像机");
        light1.turnOn("1号灯");
        light2.turnOn("2号灯");
        light3.turnOn("3号灯");
        sensor.activate();
        alarm.activate();
    }
}

仪器类:

public class Camera {

    public void turnOn(String code) {
        System.out.println("打开录像机:" + code);
    }

    public void turnOff(String code) {
        System.out.println("关闭录像机:" + code);
    }

    public void rotate(String code) {
        System.out.println("转动录像机:" + code);
    }
}


public class Light {

    public void turnOn(String code) {
        System.out.println("打开灯:" + code);
    }

    public void turnOff(String code) {
        System.out.println("关闭灯:" + code);
    }

    public void changeBulb(String code) {
        System.out.println("换灯泡:" + code);
    }
}


public class Sensor {

    public void activate() {
        System.out.println("启动感应器");
    }

    public void deactivate() {
        System.out.println("关闭感应器");
    }

    public void trigger() {
        System.out.println("触发感应器");
    }
}


public class Alarm {

    public void activate() {
        System.out.println("启动警报器");
    }

    public void deactivate() {
        System.out.println("关闭警报器");
    }

    public void ring() {
        System.out.println("拉响警报器");
    }
    public void stopRing() {
        System.out.println("停掉警报器");
    }
}

下面修改使用门面模式:

加一个门面角色类:

public class SecurityFacade {

    Camera camera1 = new Camera(), camera2 = new Camera();
    Light light1 = new Light(), light2 = new Light(), light3 = new Light();
    Sensor sensor = new Sensor();
    Alarm alarm = new Alarm();

    public void activate() {
        camera1.turnOn("1号录像机");
        camera2.turnOn("2号录像机");
        light1.turnOn("1号灯");
        light2.turnOn("2号灯");
        light3.turnOn("3号灯");
        sensor.activate();
        alarm.activate();
    }

    public void deactivate() {
        camera1.turnOff("1号录像机");
        camera2.turnOff("2号录像机");
        light1.turnOff("1号灯");
        light2.turnOff("2号灯");
        light3.turnOff("3号灯");
        sensor.deactivate();
        alarm.deactivate();
    }
}

修改Client类:

public class Client {

    public static void main(String[] args) {
        SecurityFacade facade = new SecurityFacade();
        facade.activate();
    }
}

类图: