State Design Pattern in Java


         State design pattern - an FSM with two states and one event
(distributed transition logic - logic in the derived state classes)
  1. Create a "wrapper" class that models the state machine
  2. The wrapper class maintains a "current" state object
  3. All client requests are simply delegated to the current state object and the wrapper object's "this" pointer is passed
  4. Create a state base class that makes the concrete states interchangeable
  5. The State base class specifies any useful "default" behavior
  6. The State derived classes only override the messages they need to o/r
  7. The State methods will change the "current" state in the "wrapper"
import java.io.*;
                                             //  Event - push
// 1. The "wrapper" class                    //  State   ----
class Button {                              //   ON      OFF
   // 2. The "current" state object          //   OFF     ON
   private State current;

   public Button()                   { current = OFF.instance(); }
   public void setCurrent( State s ) { current = s; }

   // 3. The "wrapper" always delegates to the "wrappee"
   public void push()                { current.push( this ); }
}

// 4. The "wrappee" hierarchy
class State {
   // 5. Default behavior can go in the base class
   public void push( Button b )  {              
      b.setCurrent( OFF.instance() );
      System.out.println( "   turning OFF" );
   }
}

class ON extends State {
   private static ON inst = new ON();
   private ON() { }

   public static State instance() { return inst; }
}

class OFF extends State {
   private static OFF inst = new OFF();
   private OFF() { }

   public static State instance() { return inst; }
   // 6. Override only the necessary methods
   public void push( Button b ) {
      // 7. The "wrappee" may callback to the "wrapper"
      b.setCurrent( ON.instance() );
      System.out.println( "   turning ON" ); 
   }
}

public class StateToggle {
   public static void main( String[] args ) throws IOException {
      InputStreamReader is = new InputStreamReader( System.in );
      int ch;
      Button btn = new Button();
      while (true) {
         System.out.print( "Press 'Enter'" );
         ch = is.read();    ch = is.read();
         btn.push();
      }
   }
}

Output

D:\Java> java StateToggle
Press 'Enter'
   turning ON
Press 'Enter'
   turning OFF
Press 'Enter'
   turning ON
Press 'Enter'
   turning OFF

Code examples