inner classes & control frameworks

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangbingfengf98/article/details/85883200

1. common control framework example:

Here is the interface that describes any control event. The default behavior is to perform the control based on time.

// innerclasses/controller/Event.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// The common methods for any control event
package innerclasses.controller;

import java.time.*; // Java 8 time classes

public abstract class Event {
  private Instant eventTime;
  protected final Duration delayTime;

  public Event(long millisecondDelay) {
    delayTime = Duration.ofMillis(millisecondDelay);
    start();
  }

  public void start() { // Allows restarting
    eventTime = Instant.now().plus(delayTime);
  }

  public boolean ready() {
    return Instant.now().isAfter(eventTime);
  }

  public static void main(String[] args) {
    System.out.println("Instant.now():" + Instant.now()); // default utc time
  }

  public abstract void action();
}
/* My Output
Instant.now():2019-01-05T14:49:15.944Z
*/

2. actual control framework

// innerclasses/controller/Controller.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// The reusable framework for control systems
package innerclasses.controller;

import java.util.*;

public class Controller {
  // A class from java.util to hold Event objects:
  private List<Event> eventList = new ArrayList<>();

  public void addEvent(Event c) {
    eventList.add(c);
  }

  public void run() {
    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<>(eventList))
        if (e.ready()) {
          System.out.println(e);
          e.action();
          eventList.remove(e);
        }
  }
}

We know nothing about exactly what an Event does. And this is the crux of the design---how it "separates the things that change from the things that stay the same."Use above example, we express different actions by creating different Event subclasses.

Inner classes donot need do this, they allow two things:

  • 1. The entire implementation of a control framework is created in a single class, thereby encapsulating everything that’s unique about that implementation. Inner classes are used to express the many different kinds of action() necessary to solve the problem.
  • 2. Inner classes keep this implementation from becoming awkward, because you easily access any of the members in the outer class. Without this, the code might become unpleasant enough that you’d seek an alternative.

Consider a  particular implemention of the control framework:

// innerclasses/GreenhouseControls.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// 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.

import innerclasses.controller.*;

public class GreenhouseControls extends Controller {
  private boolean light = false;

  public class LightOn extends Event {
    public LightOn(long delayTime) {
      super(delayTime);
    }

    @Override
    public void action() {
      // Put hardware control code here to
      // physically turn on the light.
      light = true;
    }

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

  public class LightOff extends Event {
    public LightOff(long delayTime) {
      super(delayTime);
    }

    @Override
    public void action() {
      // Put hardware control code here to
      // physically turn off the light.
      light = false;
    }

    @Override
    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() {
      // Put hardware control code here.
      water = true;
    }

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

  public class WaterOff extends Event {
    public WaterOff(long delayTime) {
      super(delayTime);
    }

    @Override
    public void action() {
      // Put hardware control code here.
      water = false;
    }

    @Override
    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() {
      // Put hardware control code here.
      thermostat = "Night";
    }

    @Override
    public String toString() {
      return "Thermostat on night setting";
    }
  }

  public class ThermostatDay extends Event {
    public ThermostatDay(long delayTime) {
      super(delayTime);
    }

    @Override
    public void action() {
      // Put hardware control code here.
      thermostat = "Day";
    }

    @Override
    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);
    }

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

    @Override
    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 e : eventList) addEvent(e);
    }

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

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

  public static class Terminate extends Event {
    public Terminate(long delayTime) {
      super(delayTime);
    }

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

    @Override
    public String toString() {
      return "Terminating";
    }
  }
}
// innerclasses/GreenhouseController.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Configure and execute the greenhouse system

import innerclasses.controller.*;

public class GreenhouseController {
  public static void main(String[] args) {
    GreenhouseControls gc = new GreenhouseControls();
    // Instead of using code, you could parse
    // configuration information from a text file:
    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));
    gc.addEvent(new GreenhouseControls.Terminate(5000));
    gc.run();
  }
}
// I need to review it later.
/* Output:
Thermostat on night setting
Light is on
Light is off
Greenhouse water is on
Greenhouse water is off
Bing!
Thermostat on day setting
Bing!
Restarting system
Thermostat on night setting
Light is on
Light is off
Greenhouse water is on
Bing!
Greenhouse water is off
Thermostat on day setting
Bing!
Restarting system
Thermostat on night setting
Light is on
Light is off
Bing!
Greenhouse water is on
Greenhouse water is off
Terminating
*/

references:

1. On Java 8 - Bruce Eckel

2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/innerclasses/controller/Event.java

3. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/innerclasses/controller/Controller.java

4. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/innerclasses/GreenhouseController.java

5. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/innerclasses/GreenhouseControls.java

猜你喜欢

转载自blog.csdn.net/wangbingfengf98/article/details/85883200