State Design Pattern

The State Design Pattern allows us to change the behaviour of an object based on it’s current state. Sometimes we want a class to behave differently in different state, this pattern allows us to abstract out state specific code form context object and model it as a composition of state object. For any state specific behaviour, context object delegates control to state object. All state classes must implement State interface that declares methods representing the behaviors of a particular state.

Important points about State pattern

  • State pattern allows the subject to vary its behaviour based on its current state.
  • Each state of the subject can be modelled as a class implementing a common State interface.
  • Each state object is responsible to performing state specific tasks.
  • A subject implements all behaviours which are independent of state and has a state object for performing state specific tasks.
  • The subject gets its state specific behaviour by delegating it to the current state object.
  • Whenever state of a system changes, its state object should also change to appropriate state handler.
  • Transition of state of subject can be handles by states or subject itself.
  • It is a behavioral design pattern.

Advantages of State Pattern

  • It simplifies the code of subject(Context). Subject should not contain any state specific if/else logic inside it’s class.
  • It helps in maintaining better ownership of state specific behaviours. A state class is fully responsible for how subject should behave in this state.
  • We can modify behaviour of any state class without affecting Subject or other state class.
  • We can add new states of subject without changing subject.
  • We can implement lifecycle of subject or a workflow as various states.

When we should use State Pattern

When an object can have multiple internal states and it’s behaviour varies as per its current states.

Implementation of State Design Pattern

State_Pattern

First of all, we will declare a State interface having ‘toggle’ method to execute state specific logic. All concrete state classes must implement this interface.

Implementation of State Design Pattern

State.java

public interface State {
   public void toggle(Switch sw);
}

OnState and OffState are concrete implemention of Switch interface representing the two possible state of a switch. Their toggle method contains state specific logic implementation.

Implementation of State Design Pattern 2

OnState.java

public class OnState implements State { 
    @Override
    public void toggle(Switch sw){
      // Write OnState specific code here
      System.out.println("Switch is in ON State.. Turning it OFF");
      sw.setState(new OffState());
    }
}

OffState.java

public class OffState implements State {
  
    @Override
    public void toggle(Switch sw){
      // Write OffState specific code here
      System.out.println("Switch is in OFF State.. Turning it ON");
      sw.setState(new OnState());
    }
}

Switch is the Context object that can have two possible states ON and OFF. It compose a State object for delegation of any state specific behaviour.

Implementation of State Design Pattern 1

Switch.java

public class Switch {
    private State state;
  
    public Switch(State state){
        this.state = state;
    }
  
    public void setState(State state){
        this.state = state;
    }
  
    public void toggleSwitch(){
        state.toggle(this);
    }
}

StatePatternExample create instance of Switch class and initialize it’s state with OnState. It changes the state of switch by call toggle method.

State Design Pattern

StatePatternExample.java

public class StatePatternExample {
    public static void main(String args[]){
        Switch sw = new Switch(new OnState());
      
        // Changing the state of switch
        sw.toggleSwitch();  // OFF
        sw.toggleSwitch();  // ON
        sw.toggleSwitch();  // OFF
        // Overriding the state of the swith to ON
        sw.setState(new OnState());
        sw.toggleSwitch(); // OFF
        sw.toggleSwitch();  //ON
    } 
}

Output

Switch is in ON State.. Turning it OFF
Switch is in OFF State.. Turning it ON
Switch is in ON State.. Turning it OFF
Switch is in ON State.. Turning it OFF
Switch is in OFF State.. Turning it ON