DEV Community

Dev Cookies
Dev Cookies

Posted on

πŸ“ Day Nine: State Design Pattern in Java

πŸ€” 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 or switch-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); } 
Enter fullscreen mode Exit fullscreen mode

βœ… 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()); } } 
Enter fullscreen mode Exit fullscreen mode

⏸️ 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."); } } 
Enter fullscreen mode Exit fullscreen mode

βœ… 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); } } 
Enter fullscreen mode Exit fullscreen mode

βœ… 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 } } 
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ Output

Resuming the music... Already playing! Pausing the music... Already paused. 
Enter fullscreen mode Exit fullscreen mode

πŸ“¦ Structure Summary

+-------------------+ +------------------+ | Context |<>------->| State | +-------------------+ +------------------+ | - state: State | | + play(context) | | + pressPlay() | | + pause(context) | | + pressPause() | +------------------+ +-------------------+ ^ ^ | | +------------------+ +------------------+ | PlayingState | | PausedState | +------------------+ +------------------+ 
Enter fullscreen mode Exit fullscreen mode

🧠 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."); } } } 
Enter fullscreen mode Exit fullscreen mode
  • 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)