State Design
Pattern
The State Design Pattern is a behavioral design
pattern that lets an object change its behavior when its internal
state changes. It appears as if the object changed its class.
๐ง Key Concepts
Concept |
Description |
Context |
The object whose behavior changes depending on its state |
State |
An interface that defines common behavior for all states |
ConcreteState |
Classes that implement the State interface with specific
behavior |
๐งพ Problem It Solves
Without the State pattern, you might have code like this:
if (state.equals("RED")) {
stop();
} else if (state.equals("GREEN")) {
go();
}
This becomes harder to maintain as you add more states and
behaviors.
๐ฆ Example: Traffic Light
System
A traffic light can be in 3 states:
- ๐ด
Red – Cars must stop.
- ๐ข
Green – Cars can go.
- ๐ก
Yellow – Cars should slow down.
The light should change from:
➡️ Red → Green → Yellow → Red →
...
ADVANTAGES OF STATE PATTERN
Benefit |
Description |
Removes complex if-else logic |
Each state has its own class |
Easy to add new states |
Just create a new class implementing State |
Promotes Open/Closed Principle |
Classes are open for extension, closed for modification |
⚠️ DISADVANTAGES
Drawback |
Description |
More classes to manage |
One class per state can be a lot in large systems |
Overhead for simple state logic |
Sometimes an enum + switch is simpler |
๐ When to Use the State
Pattern
- When
an object must change behavior based on its state
- When
there are many conditionals based on the state
- When
the state transitions are complex or likely to grow
Exmple:1
package statedesignpattern;
public interface State {
void handleRequest();
}
package statedesignpattern;
public class DraftState implements
State {
@Override
public
void handleRequest() {
System.out.println("Document
is in Draft state.");
}
}
package statedesignpattern;
public class ModerationState implements
State{
@Override
public
void handleRequest() {
System.out.println("Document
is under Moderation.");
}
}
package statedesignpattern;
public class PublishState implements
State {
@Override
public
void handleRequest() {
System.out.println("Document
is Published.");
}
}
package statedesignpattern;
public class DocumentContext {
private
State currentState;
public
DocumentContext() {
//
default state
this.currentState
= new DraftState();
}
public
void setState(State state) {
this.currentState
= state;
}
public
void applyState() {
currentState.handleRequest();
}
}
package statedesignpattern;
public class Main {
public
static void main(String[] args) {
DocumentContext
context = new DocumentContext();
context.applyState();
// Draft
context.setState(new
ModerationState());
context.applyState();
// Moderation
context.setState(new
PublishState());
context.applyState();
// Published
}
}
o/p:
Document is in Draft state.
Document is under Moderation.
Document is Published.
Example :2
package statedesignpattern.trafficlightexample;
public interface State {
void
handle(TrafficLightContext context);
}
package statedesignpattern.trafficlightexample;
public class RedLightState implements
State {
@Override
public
void handle(TrafficLightContext context) {
System.out.println("๐ด
Red Light - STOP");
context.setState(new GreenLightState());
}
}
package statedesignpattern.trafficlightexample;
public class GreenLightState implements
State{
@Override
public
void handle(TrafficLightContext context) {
System.out.println("๐ข
Green Light - GO");
context.setState(new
YellowLightState());
}
}
package statedesignpattern.trafficlightexample;
public class YellowLightState implements
State {
@Override
public
void handle(TrafficLightContext context) {
System.out.println("๐ก
Yellow Light - SLOW DOWN");
context.setState(new
RedLightState());
}
}
package statedesignpattern.trafficlightexample;
public class TrafficLightContext {
private
State currentState;
public
TrafficLightContext() {
this.currentState
= new RedLightState();// Initial state
}
public
void setState(State state) {
this.currentState
= state;
}
public
void change() {
currentState.handle(this);
}
}
package statedesignpattern.trafficlightexample;
public class Main {
public
static void main(String[] args) {
TrafficLightContext
trafficLightContext = new TrafficLightContext();
for
(int i = 0; i < 6; i++) {
trafficLightContext.change();
try
{
Thread.sleep(1000);
// simulate delay
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
o/p:
๐ด Red Light - STOP
๐ข Green Light - GO
๐ก Yellow Light - SLOW
DOWN
๐ด Red Light - STOP
๐ข Green Light - GO
๐ก Yellow Light - SLOW
DOWN