Question: How does this java code implement a car that never stops running? The Event-Driving Programming Model in Java consists of 3 type objects: The source
How does this java code implement a car that never stops running?
The Event-Driving Programming Model in Java consists of 3 type objects:
The source
The event
The listener
Example
we are modeling a simple car object, which can fire a SpeedEvent. The listener is SpeedListener interface. Max speed is temporarily set to 60MPH, min speed 40, and the default 50 when the car starts driving on the highway.
When the car runs too fast or too slow, it fires SpeedEvent. the SpeedEvent is
public class SpeedEvent { private int maxSpeed; private int minSpeed; private int currentSpeed; public SpeedEvent(/*Object source, */ int maxSpeed, int minSpeed, int currentSpeed) { // super(source); this.maxSpeed = maxSpeed; this.minSpeed = minSpeed; this.currentSpeed = currentSpeed; } // and some getters here } Corresponding SpeedListener declares 2 handlers:
public interface SpeedListener { public void speedExceeded(SpeedEvent e); public void speedGoneBelow(SpeedEvent e); } Come back to the Car, it maintains a list of SpeedListeners:
private ArrayList speedListenerList = new ArrayList();
The register method for the SpeedListener:
// Register an event listener public synchronized void addSpeedListener(SpeedListener listener) { if (!speedListenerList.contains(listener)) { speedListenerList.add(listener); } } When the car speeds up:
public void speedUp(int increment) { this.currentSpeed += increment; if (this.currentSpeed > this.maxSpeed) { // fire SpeedEvent processSpeedEvent(new SpeedEvent(this.maxSpeed, this.minSpeed, this.currentSpeed)); } } We see that when the current speed exceeds the max speed, an EventSpeed object is created with relevant information: the source, max and current speed. And then fire that EventSpeed object:
private void processSpeedEvent(SpeedEvent speedEvent) { ArrayList tempSpeedListenerList; synchronized (this) { if (speedListenerList.size() == 0) return; tempSpeedListenerList = (ArrayList) speedListenerList.clone(); } for (SpeedListener listener : tempSpeedListenerList) { listener.speedExceeded(speedEvent); listener.speedGoneBelow(speedEvent); } } This processSpeedEvent(SpeedEvent e) method is to be executed when the SpeedEvent is fired. It calls each handler of each SpeedListener object in the speedListenerList, to notify and do something about that event.
That we has created and fired the event, and delegated to the listener to process the event. It's up to the client code to implement the concrete handler(s).
* Note: the use of 'synchronized' and 'clone' is because a new listener might be added to, or the current listener might be removed from the speedListenerList while the processSpeedEvent() method is running. That leads to the corruption of speedListenerList.
It seems all done. Now is the client code (with main method) to make use of above custom Car and SpeedEvent-SpeedListener pair.
public static void main(String[] args) { Car myCar = new Car(60, 40, 50); SpeedListener listener = new MySpeedListener(); myCar.addSpeedListener(listener); // Add more listeners if you want myCar.speedUp(50); // fires SpeedEvent myCar.speedUp(50); // fires SpeedEvent myCar.slowDown(70); myCar.slowDown(70); // fires SpeedEvent } The inner class MySpeedListener defines custom concrete handler(s) as follow:
// Inner class private static class MySpeedListener implements SpeedListener { @Override public void speedExceeded(SpeedEvent e) { if (e.getCurrentSpeed() > e.getMaxSpeed()) { System.out.println("Alert! You have exceeded " + (e.getCurrentSpeed() - e.getMaxSpeed() + " MPH!")); } } @Override public void speedGoneBelow(SpeedEvent e) { if (e.getCurrentSpeed() < e.getMinSpeed()) { System.out.println("Uhm... you are driving " + e.getCurrentSpeed() + " MPH. Speed up!"); } } } Or if you don't want to use inner class, you can use anonymous class instead:
public static void main(String[] args) { Car myCar = new Car(60, 40, 50); SpeedListener listener = new MySpeedListener(); myCar.addSpeedListener(listener); // Add more listeners if you want // Anonymous inner class myCar.addSpeedListener(new SpeedListener() { @Override public void speedExceeded(SpeedEvent e) { // Code } @Override public void speedGoneBelow(SpeedEvent e) { // Code } }); myCar.speedUp(50); // fires SpeedEvent myCar.speedUp(50); // fires SpeedEvent myCar.slowDown(70); myCar.slowDown(70); // fires SpeedEvent } Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
