State in Java
Why read if you can watch?
Watch State's video tutorialState design pattern (distributed transition logic)
- 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
class FSM { // 1. The "wrapper"
private State[] states = { new A(), new B(), new C() }; // 2. States array
private int current = 0; // 3. Current state
public void on() { states[current].on( this ); } // 4. Delegation
public void off() { states[current].off( this ); } // and pass the
public void ack() { states[current].ack( this ); } // this pointer
public void changeState( int index ) { current = index; }
}
abstract class State { // 5. The State base class
public void on( FSM fsm ) { System.out.println( "error" ); } // 6. Default
public void off( FSM fsm ) { System.out.println( "error" ); } // behavior
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 ); }
}
class C extends State { // 7. Only override some messages
public void on( FSM fsm ) { System.out.println( "C + on = B" );
fsm.changeState( 1 ); } // 8. "call back to" the wrapper class
}
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
