Instead of using large conditional statements to determine how an object should behave, the State Pattern encapsulates each state as a separate class. The object delegates its behaviour to the current state object.
As the object's state changes, its behaviour changes automatically without modifying the client code.
The State Pattern is commonly used to implement workflows, order processing, document approval systems, media players, and state machines.
Structure
The State Pattern consists of the following participants.1. The State defines the common interface for all states.
2. Concrete States implement behaviour specific to a particular state.
3. The Context maintains the current state and delegates requests to it.
4. The Client interacts only with the context.

Java Implementation
Suppose an order processing system supports multiple order states. Depending on whether an order is new, paid, or shipped, invoking the same operation should produce different behaviour.Create the state interface.
public interface OrderState {
void process(Order order);
}
Create the concrete states.
public class NewOrderState implements OrderState {
@Override
public void process(Order order) {
System.out.println("Processing payment.");
order.setState(new PaidOrderState());
}
}
public class PaidOrderState implements OrderState {
@Override
public void process(Order order) {
System.out.println("Shipping order.");
order.setState(new ShippedOrderState());
}
}
public class ShippedOrderState implements OrderState {
@Override
public void process(Order order) {
System.out.println("Order already shipped.");
}
}
Create the context.
public class Order {
private OrderState state = new NewOrderState();
public void setState(OrderState state) {
this.state = state;
}
public void process() {
state.process(this);
}
}
The client processes the order.
public class Main {
public static void main(String[] args) {
Order order = new Order();
order.process();
order.process();
order.process();
}
}
Output:
Processing payment.
Shipping order.
Order already shipped.
How It Works?
The client interacts only with the Order object, which acts as the context. It has no knowledge of the individual state classes.Whenever the client invokes process(), the context delegates the request to its current OrderState implementation.
Each state performs its own behaviour and decides whether the context should transition to another state. In this example, the order moves from NewOrderState to PaidOrderState, and finally to ShippedOrderState.
This removes complex conditional logic from the context and makes it easy to introduce additional states such as Cancelled, Returned, or Delivered without modifying existing state implementations.
Advantages
1. It eliminates large conditional statements by encapsulating state-specific behaviour into separate classes.2. State transitions are localized within state classes.
3. New states can be introduced without modifying existing code.
4. It promotes cleaner, more maintainable state-driven applications.
Disadvantages
1. The pattern introduces additional state classes.2. Applications with only a few simple states may become unnecessarily complex.
3. Understanding state transitions may require examining multiple classes.
JDK Examples
The State Pattern appears throughout the Java ecosystem.1. The javax.faces.lifecycle.Lifecycle implementation in JavaServer Faces progresses through a sequence of request-processing states, with each phase exhibiting different behaviour.
2. Many workflow and state machine frameworks, such as Spring State Machine, implement the State Pattern to model state transitions and state-dependent behaviour.
Summary
The State Pattern encapsulates state-specific behaviour into separate classes and allows an object to change its behaviour automatically as its internal state changes.By replacing complex conditional logic with state objects, the pattern improves maintainability, extensibility, and the clarity of state-driven workflows.