Fundamentals 12 min read

Understanding the Chain of Responsibility Design Pattern

The Chain of Responsibility pattern links a series of handler objects so that a request can be passed along until one processes it, decoupling sender and receiver, supporting dynamic composition, runtime flexibility, and the Open/Closed principle, as illustrated by a Java leave‑approval workflow.

DaTaobao Tech
DaTaobao Tech
DaTaobao Tech
Understanding the Chain of Responsibility Design Pattern

Introduction: The Chain of Responsibility (CoR) pattern allows a request to be passed along a chain of handlers, each having a chance to process it, reducing coupling and improving flexibility.

Typical scenarios include: multiple possible handlers determined at runtime; need to submit a request without specifying a concrete receiver; dynamic composition of handlers.

Definition: CoR is a behavioral design pattern that connects multiple processing objects into a chain, decoupling sender from receivers.

Type: Object behavior pattern.

Essence: Handlers process or forward the request, enabling sender–receiver decoupling.

Benefits: decouples nodes, enhances maintainability, allows dynamic addition or reordering of handlers, supports runtime changes, and follows the Open/Closed principle.

Implementation steps:

Declare a handler interface with a method to process the request.

Create an abstract handler that holds a reference to the next handler and provides default forwarding behavior.

Implement concrete handlers that decide whether to handle the request or delegate it.

Assemble the chain either manually or via a factory.

Trigger processing from the client, optionally starting at any handler.

Example Java code:

public interface LeaveRequestProcessor {
    void processLeaveRequest(LeaveRequest request);
}
public class TeamLeaderProcessor implements LeaveRequestProcessor {
    public void processLeaveRequest(LeaveRequest request) {
        if (request.getDays() <= 3) {
            System.out.println("Team leader approved leave for " + request.getDays() + " days");
        } else {
            System.out.println("Team leader cannot handle this request");
        }
    }
}
public class DepartmentManagerProcessor implements LeaveRequestProcessor {
    public void processLeaveRequest(LeaveRequest request) {
        if (request.getDays() > 3 && request.getDays() <= 5) {
            System.out.println("Department manager approved leave for " + request.getDays() + " days");
        } else {
            System.out.println("Department manager cannot handle this request");
        }
    }
}
public class CEOProcessor implements LeaveRequestProcessor {
    public void processLeaveRequest(LeaveRequest request) {
        if (request.getDays() > 5 && request.getDays() <= 7) {
            System.out.println("CEO approved leave for " + request.getDays() + " days");
        } else {
            System.out.println("CEO cannot handle this request");
        }
    }
}
List
processors = new ArrayList<>();
processors.add(new TeamLeaderProcessor());
processors.add(new DepartmentManagerProcessor());
processors.add(new CEOProcessor());

LeaveRequest request = new LeaveRequest("John", 5);
for (LeaveRequestProcessor processor : processors) {
    processor.processLeaveRequest(request);
}

This example demonstrates how a leave‑approval workflow can be modeled with CoR, allowing easy extension or modification of approval rules without changing existing handlers.

Overall, the Chain of Responsibility pattern provides a clean, extensible way to handle requests that may require different processing steps, especially in complex business logic.

chain of responsibilityJavasoftware architecturedesign patternCode Example
DaTaobao Tech
Written by

DaTaobao Tech

Official account of DaTaobao Technology

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.