๐ค What is the State Pattern?
The State Pattern is a behavioral design pattern that allows an object to alter its behavior when its internal state changes. The object will appear to change its class.
โInstead of using
if-else
orswitch-case
to manage state transitions, encapsulate behaviors in separate state classes.โ
๐ง Real-Life Analogy
Imagine a Vending Machine:
- Idle State: Waiting for selection
- Processing State: Taking money
- Dispensing State: Giving the item
- OutOfStock State
Each state has its own behavior and transitions.
โ When to Use
- When an objectโs behavior depends on its state.
- When multiple conditional branches exist based on state.
- When the state transitions are frequent and complex.
๐ Example Use Case: Media Player
Letโs build a Media Player that can be in either:
- PlayingState
- PausedState
๐ ๏ธ Java Implementation of State Pattern
โ 1. Define the State Interface
public interface State {
void play(MediaPlayerContext context);
void pause(MediaPlayerContext context);
}
โ 2. Create Concrete States
๐ต Playing State
public class PlayingState implements State {
@Override
public void play(MediaPlayerContext context) {
System.out.println("Already playing!");
}
@Override
public void pause(MediaPlayerContext context) {
System.out.println("Pausing the music...");
context.setState(new PausedState());
}
}
โธ๏ธ Paused State
public class PausedState implements State {
@Override
public void play(MediaPlayerContext context) {
System.out.println("Resuming the music...");
context.setState(new PlayingState());
}
@Override
public void pause(MediaPlayerContext context) {
System.out.println("Already paused.");
}
}
โ 3. Context Class
public class MediaPlayerContext {
private State state;
public MediaPlayerContext() {
// Default state
this.state = new PausedState();
}
public void setState(State state) {
this.state = state;
}
public void pressPlay() {
state.play(this);
}
public void pressPause() {
state.pause(this);
}
}
โ 4. Client Code
public class StatePatternDemo {
public static void main(String[] args) {
MediaPlayerContext player = new MediaPlayerContext();
player.pressPlay(); // Resuming
player.pressPlay(); // Already playing
player.pressPause(); // Pausing
player.pressPause(); // Already paused
}
}
๐งช Output
Resuming the music...
Already playing!
Pausing the music...
Already paused.
๐ฆ Structure Summary
+-------------------+ +------------------+
| Context |<>------->| State |
+-------------------+ +------------------+
| - state: State | | + play(context) |
| + pressPlay() | | + pause(context) |
| + pressPause() | +------------------+
+-------------------+
^ ^
| |
+------------------+ +------------------+
| PlayingState | | PausedState |
+------------------+ +------------------+
๐ง Benefits
Benefit | Explanation |
---|---|
Cleaner Code | Avoids if-else hell based on state |
Encapsulation | Each state encapsulates its logic |
Flexibility | Easy to add/remove new states |
Open/Closed Principle | Add states without modifying existing code |
๐ ๏ธ Real Use Cases
- Thread lifecycle management
- UI elements (enabled, disabled, hovered, clicked)
- TCP Connection (LISTENING, SYN_SENT, ESTABLISHED)
- Traffic light system ๐ฆ
๐ซ Without State Pattern (Messy Approach)
public class MediaPlayerBad {
private String state = "PAUSED";
public void pressPlay() {
if (state.equals("PAUSED")) {
System.out.println("Resuming music...");
state = "PLAYING";
} else {
System.out.println("Already playing.");
}
}
public void pressPause() {
if (state.equals("PLAYING")) {
System.out.println("Pausing music...");
state = "PAUSED";
} else {
System.out.println("Already paused.");
}
}
}
- Hard to manage as more states are added
- Violates Open/Closed Principle
๐ง Bonus Tips
- Can be combined with Strategy if states have interchangeable behaviors.
- Helps a lot in game development and simulations.
โ Summary Table
Element | Role |
---|---|
State |
Interface for all states |
PlayingState , PausedState
|
Concrete states |
MediaPlayerContext |
Maintains the current state |
Client |
Triggers actions |
๐ Thatโs a wrap for Day 9!
Tomorrow for Day 10, weโll finish strong with the powerful Strategy Pattern โ used all over the place in Java APIs like Comparator
, payment systems, and sorting algorithms.
Wanna continue? Just say "Day 10" and weโll wrap up the series with a bang ๐ฅ.
Top comments (0)