State Design Pattern in Java

1. Definition

The State Design Pattern allows an object to change its behavior when its internal state changes. Instead of using conditional statements to dictate behavior, the object transitions between various states which define its behavior.

2. Problem Statement

How can an object adjust its behavior dynamically based on its internal conditions or state, without a convoluted series of conditional statements?

3. Solution

Use a separate class for each state (i.e., each behavior) of the object, and switch between these state classes dynamically. The object delegates its behavior to the current state object.

4. Real-World Use Cases

1. Different states of a tool in graphic design software (e.g., select, draw, erase).

2. Modes of operation in a digital camera (e.g., preview, shoot, playback).

3. Different phases of a network connection (e.g., establishing, connected, closed).

5. Implementation Steps

1. Define an interface that encapsulates the behavior associated with a particular state of the context object.

2. Implement concrete state classes that represent various states and their associated behaviors.

3. Have the context object maintain a reference to the current state object and delegate its behavior to it.

6. Implementation

// State Interface
interface State {
    void handleRequest();
}

// Concrete State
class StartState implements State {
    @Override
    public void handleRequest() {
        System.out.println("Starting...");
    }
}

// Concrete State
class StopState implements State {
    @Override
    public void handleRequest() {
        System.out.println("Stopping...");
    }
}

// Context
class Context {
    private State state;

    public Context() {
        state = null;
    }

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

    public void request() {
        state.handleRequest();
    }
}

// Client
public class StatePatternDemo {
    public static void main(String[] args) {
        Context context = new Context();

        StartState startState = new StartState();
        context.setState(startState);
        context.request();

        StopState stopState = new StopState();
        context.setState(stopState);
        context.request();
    }
}

Output:

Starting...
Stopping...

Explanation

The State Pattern allows an object to delegate its behavior to its current state instance. In the example, the Context class delegates its request() method to its current state object. The behavior changes when the state object is swapped (from StartState to StopState).

7. When to use?

Use the State Pattern when:

1. An object's behavior changes based on its state, and it must change its behavior at runtime depending on that state.

2. Operations have large, multipart conditional statements that depend on the object's state.


Comments