State Design Pattern in Java – Example Tutorial

State pattern is one of the behavioral design pattern. State design pattern is used when an Object change it’s behavior based on it’s internal state.

If we have to change the behavior of an object based on it’s state, we can have a state variable in the Object and use if-else condition block to perform different actions based on the state. State pattern is used to provide a systematic and lose-coupled way to achieve this through Context and State implementations.

Context is the class that has a State reference to one of the concrete implementations of the State and forwards the request to the state object for processing. Let’s understand this with a simple example.

Suppose we want to implement a TV Remote with a simple button to perform action, if the State is ON, it will turn on the TV and if state is OFF, it will turn off the TV.

We can implement it using if-else condition like below;

package com.journaldev.design.state;

public class TVRemoteBasic {

	private String state="";

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

	public void doAction(){
		if(state.equalsIgnoreCase("ON")){
			System.out.println("TV is turned ON");
		}else if(state.equalsIgnoreCase("OFF")){
			System.out.println("TV is turned OFF");
		}
	}

	public static void main(String args[]){
		TVRemoteBasic remote = new TVRemoteBasic();

		remote.setState("ON");
		remote.doAction();

		remote.setState("OFF");
		remote.doAction();
	}

}

Notice that client code should know the specific values to use for setting the state of remote, further more if number of states increase then the tight coupling between implementation and the client code will be very hard to maintain and extend.

Now we will use State pattern to implement above TV Remote example.

State Interface

First of all we will create State interface that will define the method that should be implemented by different concrete states and context class.

package com.journaldev.design.state;

public interface State {

	public void doAction();
}

Concrete State Implementations

In our example, we can have two states – one for turning TV on and another to turn it off. So we will create two concrete state implementations for these behaviors.

package com.journaldev.design.state;

public class TVStartState implements State {

	@Override
	public void doAction() {
		System.out.println("TV is turned ON");
	}

}
package com.journaldev.design.state;

public class TVStopState implements State {

	@Override
	public void doAction() {
		System.out.println("TV is turned OFF");
	}

}

Now we are ready to implement our Context object that will change it’s behavior based on it’s internal state.

Context Implementation

package com.journaldev.design.state;

public class TVContext implements State {

	private State tvState;

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

	public State getState() {
		return this.tvState;
	}

	@Override
	public void doAction() {
		this.tvState.doAction();
	}

}

Notice that Context also implements State and keep a reference of it’s current state and forwards the request to the state implementation.

Test Program

Now let’s write a simple program to test our implementation of TV Remote using State pattern.

package com.journaldev.design.state;

public class TVRemote {

	public static void main(String[] args) {
		TVContext context = new TVContext();
		State tvStartState = new TVStartState();
		State tvStopState = new TVStopState();

		context.setState(tvStartState);
		context.doAction();

		context.setState(tvStopState);
		context.doAction();

	}

}

Output of above program is same as the basic implementation of TV Remote without using any pattern.

The benefits of using State pattern to implement polymorphic behavior is clearly visible, the chances of error are less and it’s very easy to add more states for additional behavior making it more robust, easily maintainable and flexible. Also State pattern helped in avoiding if-else or switch-case conditional logic in this scenario.

State Pattern is very similar to Strategy Pattern, check out Strategy Pattern in Java.

Thats all for State pattern in java, I hope you liked it.
 

Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

5 Responses to "State Design Pattern in Java – Example Tutorial"

  1. Alex says:

    Nice, Thank You!!! :-)

  2. Bhukailas says:

    Hi Pankaj, I read all you design pattern articles, Based on my understnding, I feel Context and State are supposed to be two separate things but I see TVContext and TvStates are implementing same interface State.

    wouldn’t there be any other interface ?

  3. Bhukailas says:

    one more thing is If we have some 100 states we should write 100 classes, In this case also we need to something, what do you say ?

  4. Jb says:

    Thanks for the post, but I don’t think this is quite correct. The context can not be a state as it is itself changing. “Object change it’s behavior based on it’s internal state.”

  5. Krishna says:

    HI,

    TvContext can not implement state interface. I don’t think that is correct way of state pattern implementation.

Leave a Reply


3 + = four



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books