职责链模式 (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. 职责链模式的结构
角色说明
Handler(抽象处理者):定义处理请求的接口和链结构(如Approver)。ConcreteHandler(具体处理者):实现具体处理逻辑(如Manager)。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);
}
}
}
答案:
Handlerabstractsuccessor
题目3(设计题)
用职责链模式设计用户输入验证系统:
- 验证链:
NullCheck→LengthCheck→FormatCheck。 - 任一验证失败则终止,全部通过则提交。
要求:画出类图并写出关键代码。