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.
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.
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.
How the pattern responds
Model each handler as one link in a chain so it can process, short-circuit, or delegate the request onward.
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 in the Order Management domain
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) {}
}
Step by step
- Each handler performs one focused responsibility.
- The caller invokes the first handler and does not need to know the entire sequence.
- Handlers can stop processing or pass control onward.
- This works well when the processing flow is linear but still extensible.
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 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
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
How this fits today
Chain of Responsibility remains useful in Java for middleware-style pipelines, validation chains, approval flows, and request processing filters.
Where teams get it wrong
Breaking a straightforward workflow into too many handlers can create indirection without meaningful extensibility.