Java Omnibus
OOAD & Architecture / GoF patterns / Behavioral / Chain of Responsibility Pattern in Java
GoF Behavioral Java Order Management
GoF Pattern

Chain of Responsibility helps when a request should move through a sequence of handlers without the caller hardcoding every step.

Avoid coupling the sender of a request to its receiver by giving multiple objects a chance to handle the request.

Intent

What the pattern is trying to do

Avoid coupling the sender of a request to its receiver by giving multiple objects a chance to handle the request.

Problem

What force creates the need

A request must pass through several possible handlers or checks, but callers should not know the exact sequence or branching logic.

Solution

How the pattern responds

Model each handler as one link in a chain so it can process, short-circuit, or delegate the request onward.

Structure

How the moving parts fit together

A handler exposes one common entry point, holds a reference to the next handler, and decides whether to continue the chain.

Java Example

Java example in the Order Management domain

Chain of Responsibility Pattern in Java example
package org.javaomnibus.ecommerce.gof.behavioral;

public interface OrderHandler {
    void handle(Order order);
}

public abstract class OrderHandlerLink implements OrderHandler {
    private final OrderHandler next;

    protected OrderHandlerLink(OrderHandler next) {
        this.next = next;
    }

    protected void next(Order order) {
        if (next != null) {
            next.handle(order);
        }
    }
}

public final class InventoryCheckHandler extends OrderHandlerLink {
    public InventoryCheckHandler(OrderHandler next) {
        super(next);
    }

    @Override
    public void handle(Order order) {
        verifyInventory(order);
        next(order);
    }

    private void verifyInventory(Order order) {}
}
Code Walkthrough

Step by step

  1. Each handler performs one focused responsibility.
  2. The caller invokes the first handler and does not need to know the entire sequence.
  3. Handlers can stop processing or pass control onward.
  4. This works well when the processing flow is linear but still extensible.
When To Use

Where this pattern helps

  • When validation, approval, or enrichment steps should be composed in sequence
  • When the set or order of handlers may vary by policy or deployment context
When Not To Use

When a simpler design is better

  • When the workflow is simpler as one explicit method
  • When the chain becomes so opaque that debugging and reasoning suffer
Trade-Offs

What this pattern costs

  • Chains can hide control flow if naming and tracing are weak
  • Too many tiny handlers can make the flow harder to understand
Modern Relevance

How this fits today

Chain of Responsibility remains useful in Java for middleware-style pipelines, validation chains, approval flows, and request processing filters.

Common Misuse

Where teams get it wrong

Breaking a straightforward workflow into too many handlers can create indirection without meaningful extensibility.

Related Patterns

Compare with nearby choices


What To Read Next