Advanced Java September 27 ,2025

 

State Design Pattern in Java

1. Introduction

The State Pattern allows an object to change its behavior when its internal state changes.
It appears as if the object has changed its class dynamically, but actually, it’s just switching between states.

2. Real-World Analogy

Think of an ATM Machine:

  • If you insert a card but there’s no money → ATM shows “Out of Service”.
  • If ATM has money and card is inserted → ATM shows “Enter PIN”.
  • Based on the state (NoCard, HasCard, Authenticated, OutOfMoney), the ATM behaves differently.

3. Structure of State Pattern

  • State (Interface) → Defines behavior that changes with the state.
  • Concrete States → Implement specific behaviors.
  • Context (Main Object) → Maintains a reference to the current state and delegates behavior to it.

4. Custom Implementation Example

Let’s implement an ATM Machine State System.

Step 1 – State Interface

public interface ATMState {
    void insertCard();
    void enterPin(int pin);
    void withdrawCash(int amount);
}

Step 2 – Concrete States

NoCard State

public class NoCardState implements ATMState {
    private ATMMachine atm;

    public NoCardState(ATMMachine atm) {
        this.atm = atm;
    }

    @Override
    public void insertCard() {
        System.out.println("Card inserted.");
        atm.setState(atm.getHasCardState());
    }

    @Override
    public void enterPin(int pin) {
        System.out.println("No card inserted.");
    }

    @Override
    public void withdrawCash(int amount) {
        System.out.println("No card inserted.");
    }
}

HasCard State

public class HasCardState implements ATMState {
    private ATMMachine atm;

    public HasCardState(ATMMachine atm) {
        this.atm = atm;
    }

    @Override
    public void insertCard() {
        System.out.println("Card already inserted.");
    }

    @Override
    public void enterPin(int pin) {
        if (pin == 1234) {
            System.out.println("PIN correct.");
            atm.setState(atm.getAuthenticatedState());
        } else {
            System.out.println("Wrong PIN.");
            atm.setState(atm.getNoCardState());
        }
    }

    @Override
    public void withdrawCash(int amount) {
        System.out.println("Enter PIN first.");
    }
}

Authenticated State

public class AuthenticatedState implements ATMState {
    private ATMMachine atm;

    public AuthenticatedState(ATMMachine atm) {
        this.atm = atm;
    }

    @Override
    public void insertCard() {
        System.out.println("Card already inserted.");
    }

    @Override
    public void enterPin(int pin) {
        System.out.println("PIN already entered.");
    }

    @Override
    public void withdrawCash(int amount) {
        if (atm.getCash() >= amount) {
            System.out.println("Dispensed: $" + amount);
            atm.setCash(atm.getCash() - amount);

            if (atm.getCash() <= 0) {
                atm.setState(atm.getOutOfMoneyState());
            }
        } else {
            System.out.println("Insufficient funds in ATM.");
            atm.setState(atm.getOutOfMoneyState());
        }
    }
}

OutOfMoney State

public class OutOfMoneyState implements ATMState {
    private ATMMachine atm;

    public OutOfMoneyState(ATMMachine atm) {
        this.atm = atm;
    }

    @Override
    public void insertCard() {
        System.out.println("ATM out of money.");
    }

    @Override
    public void enterPin(int pin) {
        System.out.println("ATM out of money.");
    }

    @Override
    public void withdrawCash(int amount) {
        System.out.println("ATM out of money.");
    }
}

Step 3 – Context (ATM Machine)

public class ATMMachine {
    private ATMState noCardState;
    private ATMState hasCardState;
    private ATMState authenticatedState;
    private ATMState outOfMoneyState;

    private ATMState currentState;
    private int cash;

    public ATMMachine(int initialCash) {
        noCardState = new NoCardState(this);
        hasCardState = new HasCardState(this);
        authenticatedState = new AuthenticatedState(this);
        outOfMoneyState = new OutOfMoneyState(this);

        this.cash = initialCash;
        currentState = (initialCash > 0) ? noCardState : outOfMoneyState;
    }

    public void setState(ATMState state) {
        currentState = state;
    }

    public void setCash(int cash) {
        this.cash = cash;
    }

    public int getCash() {
        return cash;
    }

    public ATMState getNoCardState() { return noCardState; }
    public ATMState getHasCardState() { return hasCardState; }
    public ATMState getAuthenticatedState() { return authenticatedState; }
    public ATMState getOutOfMoneyState() { return outOfMoneyState; }

    // Delegation
    public void insertCard() { currentState.insertCard(); }
    public void enterPin(int pin) { currentState.enterPin(pin); }
    public void withdrawCash(int amount) { currentState.withdrawCash(amount); }
}

Step 4 – Client Code

public class StatePatternDemo {
    public static void main(String[] args) {
        ATMMachine atm = new ATMMachine(100);

        atm.insertCard();
        atm.enterPin(1234);
        atm.withdrawCash(50);

        atm.insertCard();
        atm.enterPin(1234);
        atm.withdrawCash(60);  // ATM out of money now
    }
}

5. Output

Card inserted.
PIN correct.
Dispensed: $50
Card inserted.
PIN correct.
Insufficient funds in ATM.

6. Advantages

  • Cleaner code by removing multiple if-else conditions.
  • Makes it easier to add new states.
  • State transitions are encapsulated within state classes.

7. Real-World Use Cases

  • ATM machines.
  • Media players (Play, Pause, Stop).
  • Traffic lights.
  • Document workflow systems (Draft, Review, Published).

 

Next- Strategy Design Pattern in Java

 

Sanjiv
0

You must logged in to post comments.

Related Blogs

Generics P...
Advanced Java August 08 ,2025

Generics Part- 2

Collection...
Advanced Java July 07 ,2025

Collections Framewor...

Mastering...
Advanced Java August 08 ,2025

Mastering Java Multi...

Annotation...
Advanced Java August 08 ,2025

Annotations

Java Memor...
Advanced Java August 08 ,2025

Java Memory Manageme...

Java Lambd...
Advanced Java August 08 ,2025

Java Lambda Expressi...

Java Funct...
Advanced Java August 08 ,2025

Java Functional Inte...

Java Strea...
Advanced Java August 08 ,2025

Java Stream API

JDBC (Java...
Advanced Java August 08 ,2025

JDBC (Java Database...

JDBC (Java...
Advanced Java September 09 ,2025

JDBC (Java Database...

Annotation...
Advanced Java August 08 ,2025

Annotations

Generics
Advanced Java August 08 ,2025

Generics

Java I/O (...
Advanced Java August 08 ,2025

Java I/O (NIO)

Introducti...
Advanced Java September 09 ,2025

Introduction to Desi...

Design Pat...
Advanced Java September 09 ,2025

Design Patterns in J...

Other Prin...
Advanced Java September 09 ,2025

Other Principles Beh...

Creational...
Advanced Java September 09 ,2025

Creational Design Pa...

In Creatio...
Advanced Java September 09 ,2025

In Creational Design...

In Creatio...
Advanced Java September 09 ,2025

In Creational Design...

Creational...
Advanced Java September 09 ,2025

Creational Design Pa...

Structural...
Advanced Java September 09 ,2025

Structural Design Pa...

In Creatio...
Advanced Java September 09 ,2025

In Creational Design...

Structural...
Advanced Java September 09 ,2025

Structural Design Pa...

Builder De...
Advanced Java September 09 ,2025

Builder Design Patte...

Structural...
Advanced Java September 09 ,2025

Structural Design Pa...

Structural...
Advanced Java September 09 ,2025

Structural Design Pa...

Structural...
Advanced Java September 09 ,2025

Structural Design Pa...

Structural...
Advanced Java September 09 ,2025

Structural Design Pa...

Structural...
Advanced Java September 09 ,2025

Structural Design Pa...

Structural...
Advanced Java September 09 ,2025

Structural Design Pa...

Design Pat...
Advanced Java September 09 ,2025

Design Patterns in J...

Chain of R...
Advanced Java September 09 ,2025

Chain of Responsibil...

Command De...
Advanced Java September 09 ,2025

Command Design Patte...

Interprete...
Advanced Java September 09 ,2025

Interpreter Design P...

Iterator D...
Advanced Java September 09 ,2025

Iterator Design Patt...

Mediator D...
Advanced Java September 09 ,2025

Mediator Design Patt...

Memento De...
Advanced Java September 09 ,2025

Memento Design Patte...

Observer D...
Advanced Java September 09 ,2025

Observer Design Patt...

Strategy D...
Advanced Java September 09 ,2025

Strategy Design Patt...

Template M...
Advanced Java September 09 ,2025

Template Method Desi...

Visitor De...
Advanced Java September 09 ,2025

Visitor Design Patte...

Prototype...
Advanced Java September 09 ,2025

Prototype Design Pat...

Java 8+ Fe...
Advanced Java October 10 ,2025

Java 8+ Features

SOLID Prin...
Advanced Java October 10 ,2025

SOLID Principles in...

Custom Imp...
Advanced Java October 10 ,2025

Custom Implementatio...

Custom Imp...
Advanced Java October 10 ,2025

Custom Implementatio...

Custom Imp...
Advanced Java October 10 ,2025

Custom Implementatio...

Custom Imp...
Advanced Java October 10 ,2025

Custom Implementatio...

How Iterat...
Advanced Java October 10 ,2025

How Iterators Work i...

How Concur...
Advanced Java October 10 ,2025

How ConcurrentHashMa...

Comparable...
Advanced Java October 10 ,2025

Comparable vs Compar...

Get In Touch

G06, Kristal Olivine Bellandur near Bangalore Central Mall, Bangalore Karnataka, 560103

+91-8076082435

techiefreak87@gmail.com