Close
State Design Pattern

State Design Pattern

Introduction

State design pattern is a behavioral design pattern, meaning which changes its behaviour based on its object’s internal state. To achieve this each object incorporated the state specific behaviour. Moreover adding new states does not affect the existing states. Lets take a closer look and discuss this in more details.

Why do we need this design?

Imagine a finite state machine with limited state. Lets go ahead and implement this with a set of API’s that should get executed when certain action takes place. Mapping of (Statea , actioni) -> Stateb has been implemented using a switch case. So far everything looks fine.

Now the client came up with new requirements, wherein several more states and their interactions where added in the switch. Somehow we managed to implement this, fine!

Now client came up with one more round of requirements, to incorporate this several more new states and interactions need to added. Do you see where it is going, soon the code will intertwine so much so that. Any changes in one place will leave a bug in other parts of the code.

Wouldn’t it be nice to have a pattern that keeps the existing states untouched and the extension by adding new states be a piece of cake. Well this is where the state design pattern comes in handy.

State Design Pattern Internals

A state design pattern can be thought of as a finite state machine. Where based on the current action objects internal states changes. This is achieved with two components

  • Context class keeps the reference current internal state, and also exposes a set of APIs to the client.
  • Interface which defines a set of methods that each of the states should implement.

State Design pattern with Example

Lets discuss an example of Electric Switch that will help explain the State design pattern in detail.

Functional Requirement of Electric Switch

  • Switch has two states ON and OFF respectively.
  • If the Switch is at ON state, hitting OFF would move the Switch to OFF state.
  • If the Switch is at OFF state, hitting ON would move the switch to ON state.
  • Switch stays in the same state if we hit the same state.

Below diagram depicting the state diagram of the above functional requirement

State design pattern class diagram for Electrical Switch

Implement of Electric switch

SwitchControl.java

package working.example.tech.DesignPattern.Behavioural.StateDesignPattern;
import working.example.tech.interfaces.TestCaseRunner;

public class SwitchControl implements TestCaseRunner {

	SwitchState currentState;
	public SwitchControl() {
		currentState = null;
	}
	public void setState(SwitchState in) {currentState = in;}
	public void ON() {
               System.out.println("User clicked ON"); 
               currentState.ON();
        }
	public void OFF() {
               System.out.println("User clicked OFF");
               currentState.OFF();
        }
	
	@Override
	public void RunTest() {
		OFF();
		ON();
		OFF();
		OFF();
		ON();
		ON();
	}
	@Override
	public void showOut() {
		// TODO Auto-generated method stub
		
	}
}

SwitchState.java

package working.example.tech.DesignPattern.Behavioural.StateDesignPattern;

public interface SwitchState {
	void ON();
	void OFF();
}

OffState.java

package working.example.tech.DesignPattern.Behavioural.StateDesignPattern;


public class OffState implements SwitchState{
    private SwitchControl ctl = null; 
        public OffState(SwitchControl ctl) {
	     this.ctl = ctl;
	}
	@Override
	public void ON() {
	      System.out.println("Switching State from OFF ---> ON");
	      ctl.setState(new OnState(ctl));
	}
		
	@Override
	public void OFF() {
	       System.out.println("Currently State is : OFF");
	}
}

OnState.java

package working.example.tech.DesignPattern.Behavioural.StateDesignPattern;


public class OnState implements SwitchState {
	private SwitchControl ctl = null;
	
	public OnState(SwitchControl ctl) {
	     this.ctl = ctl;
	}
	
	@Override
	public void ON() {
	     System.out.println("Currently State is : ON");
	}

	@Override
	public void OFF() {
             System.out.println("Switching State from ON ---> OFF");
	     ctl.setState(new OffState(ctl));
	}
}

Output

User clicked OFF
Currently State is : OFF
User clicked ON
Switching State from OFF ---> ON
User clicked OFF
Switching State from ON ---> OFF
User clicked OFF
Currently State is : OFF
User clicked ON
Switching State from OFF ---> ON
User clicked ON
Currently State is : ON

Conclusion

In this piece we touch upon very important design pattern, which is frequently used in the IT industry. We covered the basic example that helps understand the state design pattern, shall help to apply this pattern on bigger problems.

More blogs

https://www.workingexample.tech/how-to-write-a-webcrawler-for-large-language-models-at-scale-part-3/

https://www.workingexample.tech/low-level-design-of-youtubes-last-watched-video-feature-part-2/

https://www.workingexample.tech/trie-for-efficient-information-retrieval-and-its-applications/