~/app/articles/NORMAL

cat article/39.md

职责链模式 (Chain of Responsibility) 全面讲解

学习笔记
设计模式
面向对象
Java
编程模式
软件设计
职责链模式

本文全面讲解了职责链模式,包括其定义、核心思想、适用场景、与传统if-else的对比以及模式结构。通过实例和代码示例,深入浅出地介绍了如何使用职责链模式来解耦请求发送者和接收者,提高代码的可扩展性和可维护性。

date: 2025-06-22T22:26:00 tags:

  • 复习
  • 面向对象
  • Java
  • 设计模式

职责链模式 (Chain of Responsibility) 全面讲解


1. 什么是职责链模式?

职责链模式是行为型设计模式,用于将请求的发送者和接收者解耦,让多个对象都有机会处理请求。

  • 核心思想:将处理请求的对象连成一条链,请求沿链传递,直到被处理或链结束。
  • 类比:
    • 公司审批流程(员工→经理→总监→CEO)。
    • 异常处理机制(try-catch-finally)。

🔹 适用场景

  • 需要动态指定请求处理者(如日志级别过滤、权限检查)。
  • 请求需经过多个对象处理,但处理者不确定(如客服工单流转)。

2. 为什么需要职责链模式?

问题场景(传统if-else的缺陷)

假设有一个报销审批系统,根据金额不同需不同级别审批:

// 传统方式:if-else硬编码
void processRequest(double amount) {
    if (amount <= 1000) {
        manager.approve(amount);
    } else if (amount <= 5000) {
        director.approve(amount);
    } else {
        ceo.approve(amount);
    }
}

问题:审批逻辑变动需修改代码,违反开闭原则!

解决方案

将审批人组织成链,请求自动传递到对应处理者。


3. 职责链模式的结构

角色说明

  1. Handler(抽象处理者):定义处理请求的接口和链结构(如Approver)。
  2. ConcreteHandler(具体处理者):实现具体处理逻辑(如Manager)。
  3. Client(客户端):向链提交请求(如提交报销单)。

4. 示例代码(报销审批系统)

步骤1:定义抽象处理者

abstract class Approver {
    protected Approver nextApprover; // 后继处理者

    // 设置下一级审批人
    public void setNext(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    // 处理请求的抽象方法
    public abstract void processRequest(double amount);
}

步骤2:实现具体处理者

// 经理审批(<=1000)
class Manager extends Approver {
    @Override
    public void processRequest(double amount) {
        if (amount <= 1000) {
            System.out.println("经理审批通过: " + amount);
        } else if (nextApprover != null) {
            nextApprover.processRequest(amount); // 传递给下一级
        }
    }
}

// 总监审批(<=5000)
class Director extends Approver {
    @Override
    public void processRequest(double amount) {
        if (amount <= 5000) {
            System.out.println("总监审批通过: " + amount);
        } else if (nextApprover != null) {
            nextApprover.processRequest(amount);
        }
    }
}

// CEO审批(>5000)
class CEO extends Approver {
    @Override
    public void processRequest(double amount) {
        System.out.println("CEO审批通过: " + amount);
    }
}

步骤3:客户端调用

public class Client {
    public static void main(String[] args) {
        // 构建职责链
        Approver manager = new Manager();
        Approver director = new Director();
        Approver ceo = new CEO();

        manager.setNext(director);
        director.setNext(ceo);

        // 提交请求
        manager.processRequest(800);   // 经理审批
        manager.processRequest(4000);  // 总监审批
        manager.processRequest(10000); // CEO审批
    }
}

输出:

经理审批通过: 800.0  
总监审批通过: 4000.0  
CEO审批通过: 10000.0  

5. 关键点总结

🔹 纯与不纯的职责链

类型特点
纯职责链请求必须被某个处理者处理(如审批必须通过)。
不纯职责链请求可能未被处理(如异常捕获机制)。

🔹 优点

  • 解耦:请求发送者无需知道具体处理者。
  • 动态调整链:可灵活增减或调整处理者顺序。

🔹 缺点

  • 请求可能未被处理(需额外逻辑兜底)。

6. 互动实践

问题1:以下代码是职责链模式吗?为什么?

class Handler {
    void handle(Request req) {
        if (canHandle(req)) process(req);
        else System.out.println("无法处理");
    }
}

答案:不是!缺少链式传递逻辑(未调用下一个处理者)。

问题2:如何用职责链模式设计日志系统?

任务:

  • 日志级别:DEBUG < INFO < ERROR。
  • 处理者:ConsoleLogger(处理DEBUG)、FileLogger(处理INFO)、EmailLogger(处理ERROR)。
  • 补全代码:
abstract class Logger {
    protected LogLevel level;
    protected Logger ____; // 填空1
    void log(LogLevel lvl, String msg) {
        if (level.ordinal() <= lvl.ordinal()) write(msg);
        else if (next != null) ____.log(lvl, msg); // 填空2
    }
}

7. 考试练习题

题目1(概念题)

职责链模式的核心目的是?
A. 减少对象数量
B. 动态分配请求处理者
C. 强制类型转换
D. 优化算法性能

答案:B


题目2(代码填空)

补全职责链模式的代码:

abstract class Handler {
    protected Handler successor;
    
    public void setSuccessor(____ successor) {  // 填空1
        this.successor = successor;
    }
    
    public ____ void handleRequest(int request);  // 填空2
}

class ConcreteHandler extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request <= 10) {
            System.out.println("处理请求: " + request);
        } else if (____ != null) {  // 填空3
            successor.handleRequest(request);
        }
    }
}

答案:

  1. Handler
  2. abstract
  3. successor

题目3(设计题)

用职责链模式设计用户输入验证系统:

  • 验证链:NullCheck → LengthCheck → FormatCheck。
  • 任一验证失败则终止,全部通过则提交。
    要求:画出类图并写出关键代码。
$ comments --list (0)

// not signed in


// no comments yet