使用内部类实现一个控制框架 -- 《JAVA编程思想》30

控制框架是一类特殊的应用程序框架(应用程序框架是被设计用以解决某类特定问题的一个类或一组类),它用来解决响应事件的需求,主要用来响应事件的系统被称作事件驱动系统(Java Swing 库就是一个控制框架,优雅地解决了 GUI 的问题)。

要实现控制框架通常需要运用设计模式中的模版方法,模版方法包含算法的基本结构,并且会调用一个或多个可覆盖的方法,以完成算法动作,这样做可将变化的事物与保持不变的事物分离开。

控制框架的工作就是在事件“就绪”的时候执行事件,“就绪”可以是任何条件,我们假设就绪条件是基于时间触发的事件,来实现一个温室控制框架来控制灯光、水、温度调节器的开关,以及响铃和重启系统,每个行为都是完全不同的,使用控制框架可以容易地分离这些代码。

首先我们得定义一个接口描述要控制的事件,因其内部还需要定义基于时间去执行控制的方法,所以使用抽象类代替实际的接口。

在构造器内指定事件的延迟生效时间 delayTime ;start() 方法用于重置计时器,如果想要重置时间,只需再次调用 start() 方法即可; ready() 方法告诉我们何时可以调用 action() 方法。

public abstract class Event {

    //事件生效时间
    private long eventTime;

    //事件延迟时间
    protected final long delayTime;

    public Event(long delayTime) {
        this.delayTime = delayTime;
    }

    //启动事件
    public void start() {
        eventTime = System.nanoTime() + delayTime;
    }

    //判断事件是否就绪
    public boolean ready() {
        return System.nanoTime() >= eventTime;
    }

    //具体需要执行的行为
    public abstract void action();
    
}

接下来再来定义一个用来管理并触发事件的实际控制框架 Controller 。

通过 addEvent() 方法将 Event 对象被储存在 eventList 中;

run() 方法 通过 foreach 连续获取 eventList 中的 Event ,当 ready() 方法达成执行条件时,调用 Event 的 action() 方法,并通过 remove() 移除元素(一般是不能在 foreach 中移除元素的,new ArrayList<>(eventList) 相当于在每次循环开始前,把原有的集合重新排列成一个新的集合,故能在此循环中移除元素)。

下一步便可以通过控制框架 Controller 生成一个具体的应用程序框架 GreenhouseControls 类代表温室控制系统。

public class GreenhouseControls extends Controller {

    //灯光状态
    private boolean light = false;

    //打开灯光控制类
    public class LightOn extends Event {

        public LightOn(long delayTime) {
            super(delayTime);
        }

        @Override
        public void action() {
            light = true;
        }

        public String toString() {
            return "Light is on";
        }
    }

    //关闭灯光控制类
    public class LightOff extends Event {

        public LightOff(long delayTime) {
            super(delayTime);
        }

        @Override
        public void action() {
            light = false;
        }

        public String toString() {
            return "Light is off";
        }
    }

    //水开关状态
    private boolean water = false;

    //打开水开关控制类
    public class WaterOn extends Event {

        public WaterOn(long delayTime) {
            super(delayTime);
        }

        @Override
        public void action() {
            water = true;
        }

        public String toString() {
            return "Greenhouse water is on";
        }
    }

    //关闭水开关控制类
    public class WaterOff extends Event {

        public WaterOff(long delayTime) {
            super(delayTime);
        }

        @Override
        public void action() {
            water = false;
        }

        public String toString() {
            return "Greenhouse water is off";
        }
    }

    //温度调节器状态
    private String thermostat = "Day";

    //温度调节器夜间模式控制类
    public class ThermostatNight extends Event {

        public ThermostatNight(long delayTime) {
            super(delayTime);
        }

        @Override
        public void action() {
            thermostat = "night";
        }

        public String toString() {
            return "ThermostatDay on night setting";
        }
    }

    //温度调节器日间模式控制类
    public class ThermostatDay extends Event {

        public ThermostatDay(long delayTime) {
            super(delayTime);
        }

        @Override
        public void action() {
            thermostat = "Day";
        }

        public String toString() {
            return "ThermostatDay on day setting";
        }
    }

    //响铃控制类
    public class Bell extends Event {

        public Bell(long delayTime) {
            super(delayTime);
            start();
        }

        @Override
        public void action() {
            addEvent(new Bell(delayTime));
        }

        public String toString() {
            return "Bing!";
        }
    }

    //重启系统控制类
    public class Restart extends Event {

        private Event[] eventList;

        public Restart(long delayTime, Event[] eventList) {
            super(delayTime);
            this.eventList = eventList;
            for (Event event : eventList) {
                addEvent(event);
            }
        }

        @Override
        public void action() {
            for (Event event : eventList) {
                event.start();
                addEvent(event);
            }
            start();
            addEvent(this);
        }

        public String toString() {
            return "Restarting system";
        }
    }

    //关闭系统控制类
    public static class Terminate extends Event {

        public Terminate(long delayTime) {
            super(delayTime);
            start();
        }

        @Override
        public void action() {
            System.exit(0);
        }

        public String toString() {
            return "Terminating";
        }
    }

}

根据具体需求在 GreenhouseControls 实现多个不同的 Event 内部类,代表温室系统的不同行为。

light 、water、thermostat 字段都属于外围类 GreenhouseControls ,所有的内部类都可以访问修改这些字段。每个 Event 类基本都是一致的,但 Bell、Restart、Terminate 比较特殊。

Bell 类会在每次执行 action() 方法后将自身重新添加回 eventList 中等待再次执行;

Restart 类将一组 Event 对象加入到控制框架 GreenhouseControls 中,使系统能够有规律的重启自身;

Terminate 类用于关闭应用程序,当添加纳秒数作为命令行参数后,达到指定时间后,程序会自动终止。

idea 可在下图所示位置添加命令行参数。
在这里插入图片描述

在这里插入图片描述

最后创建 GreenhouseController 类来添加不同的 Event 对象来初始化系统,接下来就可以运行程序看看最终的效果。

public class GreenhouseController {

    public static void main(String[] args) {
        GreenhouseControls gc = new GreenhouseControls();
        gc.addEvent(gc.new Bell(900));
        Event[] eventList = {
                gc.new ThermostatNight(0),
                gc.new LightOn(200),
                gc.new LightOff(400),
                gc.new WaterOn(600),
                gc.new WaterOff(800),
                gc.new ThermostatDay(1400)
        };
        gc.addEvent(gc.new Restart(2000, eventList));
        if (args.length == 1) {
            gc.addEvent(new GreenhouseControls.Terminate(new Integer(args[0])));
        }
        gc.run();
    }

}
Bing!
ThermostatDay on night setting
Light is on
Light is off
Greenhouse water is on
Greenhouse water is off
ThermostatDay on day setting
Restarting system
Terminating

本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。

若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BaymaxCS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值