Java Omnibus
OOAD & Architecture / GoF patterns / Behavioral / State Pattern in Java
GoF Behavioral Java Order Management
GoF Pattern

State helps when behavior changes according to an object’s lifecycle state and conditionals are starting to dominate the design.

Allow an object to alter its behavior when its internal state changes so the object appears to change its class.

Intent

What the pattern is trying to do

Allow an object to alter its behavior when its internal state changes so the object appears to change its class.

Problem

What force creates the need

Behavior varies by lifecycle phase, and large conditional blocks are spreading state logic across the codebase.

Solution

How the pattern responds

Represent each meaningful state as an object that owns the behavior for that state and controls valid transitions.

Structure

How the moving parts fit together

A context delegates behavior to a state object, and state implementations may trigger transitions to other states.

Java Example

Java example in the Order Management domain

State Pattern in Java example
package org.javaomnibus.ecommerce.gof.behavioral;

public interface OrderState {
    void cancel(OrderContext context);
}

public final class PaidState implements OrderState {
    @Override
    public void cancel(OrderContext context) {
        context.setState(new CancelledState());
    }
}

public final class CancelledState implements OrderState {
    @Override
    public void cancel(OrderContext context) {
        throw new IllegalStateException("Order already cancelled");
    }
}
Code Walkthrough

Step by step

  1. Each state owns behavior that was previously buried in conditionals.
  2. The context delegates behavior to the active state object.
  3. This keeps lifecycle rules closer to the states they belong to.
  4. State is about lifecycle-driven behavior, not just swappable policy.
When To Use

Where this pattern helps

  • When behavior changes by lifecycle phase or status
  • When conditionals on state keep spreading and becoming error-prone
When Not To Use

When a simpler design is better

  • When state distinctions are too small to justify separate types
  • When the real problem is choosing among algorithms rather than modeling lifecycle
Trade-Offs

What this pattern costs

  • Adds more types and transitions to reason about
  • Poorly designed states can still leak transition logic everywhere
Modern Relevance

How this fits today

State remains useful in Java for order lifecycles, workflow engines, payment flows, fulfillment stages, and protocol-style objects.

Common Misuse

Where teams get it wrong

Turning every small status flag into a full state hierarchy can over-model a domain that only needed a few clear checks.

Related Patterns

Compare with nearby choices


What To Read Next