DEV Community

DevCorner2
DevCorner2

Posted on

๐Ÿงพ State Design Pattern โ€“ LLD + Java + Real-World Use Case

Allow an object to alter its behavior when its internal state changes โ€” making the object appear to change its class.


๐Ÿง  What Is the State Pattern?

The State Pattern is a behavioral design pattern that:

  • Encapsulates state-specific behavior into separate classes.
  • Delegates state transitions and behavior to these state objects.
  • Avoids conditionals (if-else, switch-case) spread across methods.

โœ… Real-World Use Cases

System/Domain Example of States
๐ŸŽซ Movie Booking SeatAvailable โ†’ Reserved โ†’ Paid โ†’ Cancelled
๐Ÿง ATM Machine CardInserted, PinVerified, CashDispensed
๐Ÿšฆ Traffic Signal Red โ†’ Yellow โ†’ Green
๐Ÿ“ถ Network Connection Connected, Disconnected, Reconnecting
๐Ÿ“„ Document Workflow Draft, Reviewed, Approved, Published

๐Ÿ“Œ When to Use It?

โœ… Use State Pattern when:

  • An object must behave differently depending on internal state.
  • You have lots of conditional logic (if/switch) that varies by state.
  • State transitions are part of business logic.

๐Ÿงฑ Pattern Structure (LLD)

Component Responsibility
State (interface) Declares operations per state
ConcreteState Implements behavior for a specific state
Context Maintains current state and delegates behavior

๐Ÿ“ UML Diagram

+---------------------+
|       Context       |
+---------------------+
| - state: State      |
| +setState(State)    |
| +handle()           |
+---------------------+
         โ–ฒ
         |
+---------------------+       +------------------------+
|       State         |<------+   ConcreteStateX       |
+---------------------+       +------------------------+
| +handle(Context)    |       | +handle(Context)       |
+---------------------+       +------------------------+
Enter fullscreen mode Exit fullscreen mode

๐Ÿ’ป Java Implementation โ€“ Vending Machine Example

Weโ€™ll model a vending machine with 3 states:

  • IdleState: Waiting for coin
  • HasCoinState: Coin inserted, ready to select item
  • DispensingState: Dispensing item

โœ… VendingState.java

public interface VendingState {
    void insertCoin(VendingMachine context);
    void selectItem(VendingMachine context);
    void dispense(VendingMachine context);
}
Enter fullscreen mode Exit fullscreen mode

โœ… IdleState.java

public class IdleState implements VendingState {
    @Override
    public void insertCoin(VendingMachine context) {
        System.out.println("๐Ÿช™ Coin inserted. Ready to select item.");
        context.setState(new HasCoinState());
    }

    @Override
    public void selectItem(VendingMachine context) {
        System.out.println("โŒ Insert coin first.");
    }

    @Override
    public void dispense(VendingMachine context) {
        System.out.println("โŒ Cannot dispense. No item selected.");
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… HasCoinState.java

public class HasCoinState implements VendingState {
    @Override
    public void insertCoin(VendingMachine context) {
        System.out.println("โŒ Coin already inserted.");
    }

    @Override
    public void selectItem(VendingMachine context) {
        System.out.println("๐Ÿ“ฆ Item selected. Dispensing now...");
        context.setState(new DispensingState());
    }

    @Override
    public void dispense(VendingMachine context) {
        System.out.println("โŒ Select an item first.");
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… DispensingState.java

public class DispensingState implements VendingState {
    @Override
    public void insertCoin(VendingMachine context) {
        System.out.println("โŒ Please wait. Dispensing in progress.");
    }

    @Override
    public void selectItem(VendingMachine context) {
        System.out.println("โŒ Already dispensing.");
    }

    @Override
    public void dispense(VendingMachine context) {
        System.out.println("โœ… Item dispensed. Back to idle.");
        context.setState(new IdleState());
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… VendingMachine.java (Context)

public class VendingMachine {
    private VendingState currentState;

    public VendingMachine() {
        this.currentState = new IdleState(); // Initial state
    }

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

    public void insertCoin() {
        currentState.insertCoin(this);
    }

    public void selectItem() {
        currentState.selectItem(this);
    }

    public void dispense() {
        currentState.dispense(this);
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… Client.java

public class StatePatternDemo {
    public static void main(String[] args) {
        VendingMachine machine = new VendingMachine();

        machine.selectItem();    // โŒ Insert coin first.
        machine.insertCoin();    // ๐Ÿช™ Coin inserted.
        machine.insertCoin();    // โŒ Already inserted
        machine.selectItem();    // ๐Ÿ“ฆ Dispensing
        machine.dispense();      // โœ… Dispensed, back to Idle
    }
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿงช Output

โŒ Insert coin first.
๐Ÿช™ Coin inserted. Ready to select item.
โŒ Coin already inserted.
๐Ÿ“ฆ Item selected. Dispensing now...
โœ… Item dispensed. Back to idle.
Enter fullscreen mode Exit fullscreen mode

โœจ Benefits

Benefit Description
โœ… Open/Closed Easily add new states without touching context
โœ… Clean code No complex if-else for state logic
โœ… Maintainability Each state is isolated, testable, reusable
โœ… Realistic modeling Closer to real-world workflows

โš ๏ธ Limitations

  • โŒ Number of classes can grow with complex state machines
  • โš ๏ธ Context object may need to expose internals (setState)
  • ๐Ÿ”„ May be overkill for simple linear flows

๐Ÿงพ Summary

Aspect Value
Pattern Type Behavioral
Intent Change behavior by state
Java Features Used Interfaces, Polymorphism, Delegation
Ideal for Workflow engines, UI flows, devices, FSMs

๐ŸŽฏ Interview Tip

If asked to build a Ticket Booking System, Document Approval Workflow, or Game Character State, the State Pattern is often the cleanest and most extensible design choice.


Top comments (0)