java 内部类与控制框架
应用程序控制框架(application framework)就是设计解决某类特殊问题的一个类,或一组类,要运用某个应用程序框架,通常是继承一个类或多个类,并覆盖这些方法.在覆盖的方法中编写代码定制应用程序框架提供的解决方案,以解决你的问题
控制框架是一类特殊应用程序框架,它用来解决响应事件的需求,主要用来响应事件的系统被称为事件驱动系统,(最常见的是GUI)
应用框架设计中,设计的关键是"变化的事物和不变的事物相互分离"
//: innerclasses/controller/Event.java // The common methods for any control event. package object; public abstract class Event {//因为其默认的行为是基于时间去执行控制的,所以使用抽象类代替实际的接口 private long eventTime; protected final long delayTime; public Event(long delayTime) { this.delayTime = delayTime; start(); } public void start() { // Allows restarting//当运行Event并调用start()时,构造器就会捕获时间 eventTime = System.nanoTime() + delayTime;//当前时间加上延迟时间,start()是一个独立方法,而没有包含在构造器中 } //这样就可以在事件运行以后重新启动计时器 public boolean ready() { return System.nanoTime() >= eventTime; } public abstract void action();//对于控制行为,控制框架并不包含具体的信息,那些算的action()部分通过继承action()来来提供 } ///:~
下面的是一个用来管理并触发事件的实际控制框架,
//: innerclasses/controller/Controller.java // The reusable framework for control systems. package object; import java.util.*; public class Controller { // A class from java.util to hold Event objects: //List是一个容器,list<Event>(读作Event的列表> //add()添加Object到LIst的尾端, size()得到List中的元素个数 //foreach语法用来连续获取List中的Event //remove()方法用来从list列表移除指定的Event private List<Event> eventList = new ArrayList<Event>(); public void addEvent(Event c) { eventList.add(c); } public void run() { //该方法遍历eventlist,寻找就绪的ready(),并调用相应的方法 while(eventList.size() > 0) // Make a copy so you're not modifying the list // while you're selecting the elements in it: for(Event e : new ArrayList<Event>(eventList)) if(e.ready()) { System.out.println(e); e.action(); eventList.remove(e); } } } ///:~
内部类允许:
1)控制框架的完整是由单个的类创建的,从而使得实现的细节被封装了起来,内部类用来表示解决问题所必需的各种不同的action()
2)内部类能够很容易地访问外围类的任意成员,所以可以避免这种实现变得笨拙,
下面是此框架的一个特定实现,控制温度的运作:控制灯光,水,温度调节器的开关,以及响铃和重新启动系统,每个行为都是完全不同的,控制框架的设计使得分离这些不同的代码变得非常容易,使用内部类,可以在单一的类里面产生对同一个基类Event的多种导出版本,对于温度系统的每一种行为,都继承一个新的Event内部类,并在要实现的action()中编写控制代码
//: innerclasses/GreenhouseControls.java // This produces a specific application of the // control system, all in a single class. Inner // classes allow you to encapsulate different // functionality for each type of event. package object; public class GreenhouseControls extends Controller { private boolean light = false; public class LightOn extends Event { public LightOn(long delayTime) { super(delayTime); } public void action() { // Put hardware control code here to // physically turn on the light. light = true; } public String toString() { return "Light is on"; } } public class LightOff extends Event { public LightOff(long delayTime) { super(delayTime); } public void action() { // Put hardware control code here to // physically turn off the light. light = false; } public String toString() { return "Light is off"; } } private boolean water = false; public class WaterOn extends Event { public WaterOn(long delayTime) { super(delayTime); } public void action() { // Put hardware control code here. water = true; } public String toString() { return "Greenhouse water is on"; } } public class WaterOff extends Event { public WaterOff(long delayTime) { super(delayTime); } public void action() { // Put hardware control code here. 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); } public void action() { // Put hardware control code here. thermostat = "Night"; } public String toString() { return "Thermostat on night setting"; } } public class ThermostatDay extends Event { public ThermostatDay(long delayTime) { super(delayTime); } public void action() { // Put hardware control code here. thermostat = "Day"; } public String toString() { return "Thermostat on day setting"; } } // An example of an action() that inserts a // new one of itself into the event list: public class Bell extends Event { public Bell(long delayTime) { super(delayTime); } public void action() { addEvent(new Bell(delayTime));//Bell控制响铃然后再事件列表中增加一个Bell对象,于是过一会二它可以再次响铃 } public String toString() { return "Bing!"; } } public class Restart extends Event {//Restart()可以控制系统有规律的重启 private Event[] eventList; public Restart(long delayTime, Event[] eventList) { super(delayTime); this.eventList = eventList; for(Event e : eventList) addEvent(e); } public void action() { for(Event e : eventList) { e.start(); // Rerun each event addEvent(e); } start(); // Rerun this Event addEvent(this); } public String toString() { return "Restarting system"; } } public static class Terminate extends Event { public Terminate(long delayTime) { super(delayTime); } public void action() { System.exit(0); } public String toString() { return "Terminating"; } } } ///:~
下面的类通过创建一个GreenhouseControls对象,并添加各种不同的Event对象来配置该系统,这是命令设计模式的一个例子再eventlist中的每一个被封装成对象的请求
//: innerclasses/GreenhouseController.java // Configure and execute the greenhouse system. // {Args: 5000} package object; public class GreenhouseController { public static void main(String[] args) { GreenhouseControls gc = new GreenhouseControls(); // Instead of hard-wiring, you could parse // configuration information from a text file here: 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(); } } /* Output: Bing! Thermostat on night setting Light is on Light is off Greenhouse water is on Greenhouse water is off Thermostat on day setting Restarting system Terminating *///:~