Implementing the State Design Pattern using Enums
Posted by ryano on January 31, 2005 at 7:14 PM EST
Recently I've been reading "Head First Design Patterns" as well as
"Java 1.5 Tiger - A Developer's Notebook". Both are really good
books by the way. I was reading the chapter on the State design
pattern when it occurred to me that the new Enum feature in J2SE 5.0
would be a perfect way to implement the state design pattern.Typically, the state pattern is used to model a state transition graph allowing an object to modify its behavior as the state of the graph changes. The pattern typically defines a "state" interface containing a method declaration for each state transition in the graph. Next, a class is created for each state in the state graph. These state classes implement the "state" interface. Clients hold a reference to the current state which it treats as a "state" interface type. As the client invokes methods on the current state, the concrete state object performs some operation and updates the current state in the client. This decouples the client from the state management details.
A simple example of a state machine is a light switch. The switch has two states, on and off. The switch also has two transitions, turnOn and turnOff. If the switch is in the off state and receives a command to turnOn the switch transitions to the on state. If the switch is in the off state and is told to turn off, the switch does nothing since it is already off. If the switch is in the on state and is told to turnOff the switch transitions to the off state. Finally, if the switch is in the on state and is told to turn on the switch does nothing.
Following the typical state pattern implementation, the "state" interface would contain two methods, turnOn and turnOff. Two classes would be created to represent the two states, on and off. Each class would implement the "state" interface. The client would hold a reference to an object of the "state" interface type and call the appropriate methods on this object as events occur.
Using the Enum construct in J2SE 5.0, the entire state pattern can be contained in an enumerated type definition. The abstract methods declared in the enumerated type take the place of the "state" interface and each enumeral implements the abstract methods much like the concrete state classes implement the "state" interface.
The following enumerated type encapsulates the switch states and transitions:
enum State {
ON(1) {
public State turnOn() {
System.err.println("Already ON");
return ON;
}
public State turnOff() {
System.err.println("Turning OFF");
return OFF;
}
},
OFF(0) {
public State turnOn() {
System.err.println("Turning ON");
return ON;
}
public State turnOff() {
System.err.println("Already OFF");
return OFF;
}
};
private int val;
State(int val) {
this.val = val;
}
public abstract State turnOn();
public abstract State turnOff();
}
Here is a simple Driver that exercises the Enumerated type:public class Driver {
private State state = State.OFF;
public void go() {
System.out.print("turnOn()\t"); state = state.turnOn();
System.out.print("turnOn()\t"); state = state.turnOn();
System.out.print("turnOff()\t"); state = state.turnOff();
System.out.print("turnOff()\t"); state = state.turnOff();
System.out.print("turnOn()\t"); state = state.turnOn();
System.out.print("turnOn()\t"); state = state.turnOn();
}
public static void main(String[] args) {
new Driver().go();
}
}
Each enumeral represents a state and each abstract method represents a state transition. Each enumeral implements the state transitions and acts accordingly. As new states and transitions are introduced the user can simply update this enumerated type. This seems like an interesting way to implement the state design pattern. It also localizes the changes to one source file (excluding the Client). In the original version of the pattern the "state" interface would have to be updated with new transition methods. Each state class that implements the interface would need to add implementations of the new methods and for each new state a new class would be created.
Related Topics >>
Blog Links >>
- Login or register to post comments
- Printer-friendly version
- ryano's blog
- 4827 reads





