- Create a “wrapper” class that models the state machine
- The wrapper class contains an array of state concrete objects
- The wrapper class contains an index to its “current” state
- Client requests are delegated to the current state and “this” is passed
- Create a state base class that makes the concrete states interchangeable
- The State base class specifies default behavior for all messages
- The State derived classes only override the messages they need to
- The derived classes “call back to” the wrapper class to change its current
// 1. The "wrapper"
class FSM {
// 2. States array
private State[] states = { new A(), new B(), new C() };
// 3. Current state
private int current = 0;
// 4. Delegation and pass the this pointer
public void on() { states[current].on( this ); }
public void off() { states[current].off( this ); }
public void ack() { states[current].ack( this ); }
public void changeState( int index ) { current = index; }
}
// 5. The State base class
abstract class State {
// 6. Default behavior
public void on( FSM fsm ) { System.out.println( "error" ); }
public void off( FSM fsm ) { System.out.println( "error" ); }
public void ack( FSM fsm ) { System.out.println( "error" ); }
}
class A extends State {
public void on( FSM fsm ) { System.out.println( "A + on = C" );
fsm.changeState( 2 ); }
public void off( FSM fsm ) { System.out.println( "A + off = B" );
fsm.changeState( 1 ); }
public void ack( FSM fsm ) { System.out.println( "A + ack = A" );
fsm.changeState( 0 ); }
}
class B extends State {
public void on( FSM fsm ) { System.out.println( "B + on = A" );
fsm.changeState( 0 ); }
public void off( FSM fsm ) { System.out.println( "B + off = C" );
fsm.changeState( 2 ); }
}
// 7. Only override some messages
class C extends State {
// 8. "call back to" the wrapper class
public void on( FSM fsm ) { System.out.println( "C + on = B" );
fsm.changeState( 1 ); }
}
public class StateDemo2 {
public static void main( String[] args ) {
FSM fsm = new FSM();
int[] msgs = { 2, 1, 2, 1, 0, 2, 0, 0 };
for (int i=0; i < msgs.length; i++)
if (msgs[i] == 0) fsm.on();
else if (msgs[i] == 1) fsm.off();
else if (msgs[i] == 2) fsm.ack();
}
}
A + ack = A
A + off = B
error
B + off = C
C + on = B
error
B + on = A
A + on = C
List of State examples
C# examples
C++ examples
Delphi examples
Java examples
PHP examples