Introduction

State pattern is one of the behavioral design pattern. This pattern is used when an object changes its behavior based on its internal state. This pattern allows an object to have many different behaviors that are based on its internal state. Unlike a procedural state machine, it represents state as a full-blown class. In State pattern, we create objects which represent various states and a context object whose behavior varies as its state object changes. The context gets its behavior by delegating to the current state object it is composed with.

Intent

  • Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
  • An object-oriented state machine

Implementation

  • Context: Defines an interface to client to interact. It maintains references to concrete state object which may be used to define current state of object.
  • State: Defines interface for declaring what each concrete state should do.

Example

// Create an interface.
public interface State {
   public void doAction(Context context);
}

// Create concrete classes implementing the same interface.
public class StartState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in start state");
      context.setState(this);	
   }
}

public class StopState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in stop state");
      context.setState(this);	
   }
}

// Create Context Class.
public class Context {
   private State state;

   public Context(){
      state = null;
   }

   public void setState(State state){
      this.state = state;		
   }

   public State getState(){
      return state;
   }
}

// Use the Context to see change in behaviour when State changes.
public class StatePatternDemo {
   public static void main(String[] args) {
      Context context = new Context();

      State startState = new StartState();
      startState.doAction(context);

      StopState stopState = new StopState();
      stopState.doAction(context);
   }
}