Skip to main content
5 of 5
added 123 characters in body
Tulains Córdova
  • 39.6k
  • 13
  • 102
  • 157
  • I turned the Car into a state machine of sorts using State Pattern. Notice no switch or if-then-else statements are used for state selection.

  • In this cases all states are inner classes but it could be implemented otherwise.

  • Each state contains the valid states it can change to.

  • User is prompted for the next state in case more than one is possible, or simply to confirm in case only one is possible.

  • You can compile it and run it to test it.

  • I used a graphic dialog box because it was easier that way to run it interactively in Eclipse.

enter image description here

The UML diagram is taken from here.

import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.JOptionPane; public class Car { private State state; public static final int ST_OFF=0; public static final int ST_IDDLE=1; public static final int ST_DRIVE=2; public static final int ST_REVERSE=3; Map<Integer,State> states=new HashMap<Integer,State>(); public Car(){ this.states.put(Car.ST_OFF, new Off()); this.states.put(Car.ST_IDDLE, new Idle()); this.states.put(Car.ST_DRIVE, new Drive()); this.states.put(Car.ST_REVERSE, new Reverse()); this.state=this.states.get(Car.ST_OFF); } private abstract class State{ protected List<Integer> nextStates = new ArrayList<Integer>(); public abstract void handle(); public abstract void change(); protected State promptForState(String prompt){ State s = state; String word = JOptionPane.showInputDialog(prompt); int ch = -1; try { ch = Integer.parseInt(word); }catch (NumberFormatException e) { } if (this.nextStates.contains(ch)){ s=states.get(ch); } else { System.out.println("Invalid option"); } return s; } } private class Off extends State{ public Off(){ super.nextStates.add(Car.ST_IDDLE); } public void handle() { System.out.println("Stopped");} public void change() { state = this.promptForState("Stopped, iddle="+Car.ST_IDDLE+": "); } } private class Idle extends State{ private List<Integer> nextStates = new ArrayList<Integer>(); public Idle(){ super.nextStates.add(Car.ST_DRIVE); super.nextStates.add(Car.ST_REVERSE); super.nextStates.add(Car.ST_OFF); } public void handle() { System.out.println("Idling");} public void change() { state=this.promptForState("Idling, enter 0=off 2=drive 3=reverse: "); } } private class Drive extends State{ private List<Integer> nextStates = new ArrayList<Integer>(); public Drive(){ super.nextStates.add(Car.ST_IDDLE); } public void handle() {System.out.println("Driving");} public void change() { state=this.promptForState("Idling, enter 1=iddle: "); } } private class Reverse extends State{ private List<Integer> nextStates = new ArrayList<Integer>(); public Reverse(){ super.nextStates.add(Car.ST_IDDLE); } public void handle() {System.out.println("Reversing");} public void change() { state = this.promptForState("Reversing, enter 1=iddle: "); } } public void request(){ this.state.handle(); } public void changeState(){ this.state.change(); } public static void main (String args[]){ Car c = new Car(); c.request(); //car is stopped c.changeState(); c.request(); // car is iddling c.changeState(); // prompts for next state c.request(); c.changeState(); c.request(); c.changeState(); c.request(); } } 
Tulains Córdova
  • 39.6k
  • 13
  • 102
  • 157