Fundamentals 7 min read

Chain of Responsibility Pattern – Concept, UML Diagram, Java Implementation, Pros, Cons, and Use Cases

This article explains the Chain of Responsibility design pattern, covering its concept, UML class diagram, Java code examples, advantages, disadvantages, typical application scenarios, extensions, and comparison with the Decorator pattern in software development.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Chain of Responsibility Pattern – Concept, UML Diagram, Java Implementation, Pros, Cons, and Use Cases

Introduction The Chain of Responsibility (CoR) pattern, also known as the responsibility chain, is an object‑behavior pattern that decouples the sender of a request from its receivers by linking handlers in a chain. A request travels along the chain until a handler processes it.

UML Class Diagram The diagram consists of an abstract Handler class defining a reference to the next handler and an abstract handleRequest method, a ConcreteHandler that implements the handling logic, and a Client that assembles the chain and initiates the request.

Java Code Example – Traditional if‑else

public class LeaveApproval {
    public static void main(String[] args) {
        ExpenseReimbursement maNiuApply = new ExpenseReimbursement();
        maNiuApply.setName("Ma Niu");
        maNiuApply.setAmount(-100);
        if (maNiuApply.getAmount() < 0) {
            System.out.println("Amount error!");
        } else if (maNiuApply.getAmount() <= 500) {
            projectManagerHandle(maNiuApply);
        } else if (maNiuApply.getAmount() <= 1000) {
            departmentManagerHandle(maNiuApply);
        } else {
            managingDirectorHandle(maNiuApply);
        }
    }
    public static void projectManagerHandle(ExpenseReimbursement expense) {
        System.out.println("Project manager approved " + expense.getAmount());
    }
    public static void departmentManagerHandle(ExpenseReimbursement expense) {
        System.out.println("Department manager approved " + expense.getAmount());
    }
    public static void managingDirectorHandle(ExpenseReimbursement expense) {
        System.out.println("Managing director approved " + expense.getAmount());
    }
}

Java Code Example – CoR Implementation

public class ChainOfResponsibilityPattern {
    public static void main(String[] args) {
        // Assemble the chain
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        handler1.setNext(handler2);
        // Submit request
        handler1.handleRequest("two");
    }
}

abstract class Handler {
    private Handler next;
    public void setNext(Handler next) { this.next = next; }
    public Handler getNext() { return next; }
    public abstract void handleRequest(String request);
}

class ConcreteHandler1 extends Handler {
    @Override
    public void handleRequest(String request) {
        if (request.equals("one")) {
            System.out.println("ConcreteHandler1 handler!");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(request);
            } else {
                System.out.println("None handler!");
            }
        }
    }
}

class ConcreteHandler2 extends Handler {
    @Override
    public void handleRequest(String request) {
        if (request.equals("two")) {
            System.out.println("ConcreteHandler2 handler!");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(request);
            } else {
                System.out.println("None handler!");
            }
        }
    }
}

Advantages 1. Reduces coupling between objects; the sender does not need to know which handler will process the request. 2. Follows the Open/Closed Principle – new concrete handlers can be added without modifying existing code. 3. Increases flexibility in assigning responsibilities; the chain order can be changed at runtime. 4. Simplifies object connections by requiring only a single reference to the next handler. 5. Clarifies responsibilities, aligning with the Single Responsibility Principle.

Disadvantages 1. No guarantee that a request will be handled; it may reach the end of the chain unprocessed. 2. Long chains can affect performance due to multiple handler traversals. 3. The client must correctly configure the chain, which can introduce complexity and potential circular references.

Typical Application Scenarios • When multiple objects can handle a request and the concrete handler is determined at runtime. • When a dynamic set of handlers may be added or reordered. • When the request should be processed by one of several handlers without explicitly specifying which one.

Extensions Two variants exist: (1) Pure CoR, where each request is handled by exactly one concrete handler; (2) Impure CoR, where a handler may partially process a request and forward the remainder, possibly leaving the request unhandled.

Comparison with Decorator Pattern Both patterns involve chaining objects, but Decorator adds responsibilities to an object dynamically, whereas CoR passes a request along a chain until one object handles it.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Chain of ResponsibilityJavaSoftware Architecturedesign patternObject-Oriented
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

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.