责任链模式 (Chain of Responsibility)
当多个对象接收到请求时,责任链模式让它们依次传递处理,不会发生冲突,也不会让某个对象被过度依赖。
想象一下你是公司的一名员工,每当你有一个问题需要解决时,你通常会按流程去找相关负责人。如果问题较小,你可能直接找你的直属上司。如果上司无法解决,你会被指引到更高级的管理人员,直到问题被解决。每个管理者都有责任帮助你,但不是每个人都能解决所有问题,责任链就是这样一种流程——每个处理者都在自己的职责范围内处理问题,不会互相冲突,且每个处理者都有可能将问题传递给下一个更合适的处理者。
责任链模式就像是一个“问题处理链条”,每个对象都按照预定顺序传递请求,直到某个对象处理完成。这样,客户端无需知道哪个对象能够处理请求,只需要发出请求即可,而责任链内部会自动决定由哪个对象来处理。
趣味解读:问题接力赛!
想象你在参加一个接力赛跑,赛道上有多个选手,每个选手都在自己的赛道上跑,每当一个选手跑完后,他会将接力棒传递给下一个选手。每个选手只负责自己那一段的赛道,接力棒的传递不受阻碍,直到赛跑完成。责任链模式就像是这个接力赛,任务(问题)从一个对象传递到下一个,直到最终完成任务。而且,任何选手都不会因接力棒的传递而被迫承担其他选手的任务——每个人的责任是清晰的。
Java代码案例:责任链模式 - 审批流程
假设我们需要设计一个简单的审批流程系统,员工需要申请加薪,而加薪的审批由多个审批人逐级处理。员工提交加薪申请后,审批人会依次审查。每个审批人有自己的审批额度,如果超过了权限,他们会将申请转交给上级审批人。
// 1. 处理者接口 - 责任链中的每个处理者都实现这个接口
abstract class Approver {
protected Approver nextApprover;
// 设置下一个处理者
public void setNextApprover(Approver nextApprover) {
this.nextApprover = nextApprover;
}
// 处理请求的方法
public abstract void handleRequest(int amount);
}
// 2. 具体处理者 - 部门经理
class DepartmentManager extends Approver {
@Override
public void handleRequest(int amount) {
if (amount <= 1000) {
System.out.println("部门经理审批通过: " + amount + " 元");
} else if (nextApprover != null) {
nextApprover.handleRequest(amount);
}
}
}
// 3. 具体处理者 - 总经理
class GeneralManager extends Approver {
@Override
public void handleRequest(int amount) {
if (amount <= 5000) {
System.out.println("总经理审批通过: " + amount + " 元");
} else if (nextApprover != null) {
nextApprover.handleRequest(amount);
}
}
}
// 4. 具体处理者 - CEO
class CEO extends Approver {
@Override
public void handleRequest(int amount) {
if (amount <= 10000) {
System.out.println("CEO审批通过: " + amount + " 元");
} else {
System.out.println("审批金额超出范围,无法审批!");
}
}
}
// 5. 客户端代码 - 模拟加薪审批流程
public class Main {
public static void main(String[] args) {
Approver departmentManager = new DepartmentManager();
Approver generalManager = new GeneralManager();
Approver ceo = new CEO();
// 设置责任链
departmentManager.setNextApprover(generalManager);
generalManager.setNextApprover(ceo);
// 发起请求
System.out.println("员工申请加薪 800 元:");
departmentManager.handleRequest(800);
System.out.println("\n员工申请加薪 3000 元:");
departmentManager.handleRequest(3000);
System.out.println("\n员工申请加薪 12000 元:");
departmentManager.handleRequest(12000);
}
}
解析:
处理者接口:
Approver
是一个抽象类,它定义了handleRequest
方法,处理请求,并且维护了一个nextApprover
来链接下一个处理者。每个具体的处理者(如部门经理、总经理、CEO)都会根据自己的职责范围来处理请求,若无法处理,会将请求交给下一个处理者。具体处理者:如
DepartmentManager
、GeneralManager
、CEO
等类都实现了Approver
接口,定义了自己的审批权限。每个处理者会根据申请的金额判断是否可以审批,如果超出权限就将请求传递给下一个处理者。客户端代码:在客户端,首先创建了三个处理者,并设置责任链的顺序(部门经理 -> 总经理 -> CEO)。然后,模拟员工申请加薪,分别发起不同金额的加薪请求,责任链会依次处理。
运行结果:
员工申请加薪 800 元:
部门经理审批通过: 800 元
员工申请加薪 3000 元:
总经理审批通过: 3000 元
员工申请加薪 12000 元:
审批金额超出范围,无法审批!
实际应用场景:
权限管理:在权限管理系统中,多个级别的用户可能拥有不同的访问权限。责任链模式能够帮助系统按顺序处理用户的权限请求,直到找到合适的权限等级进行授权。
日志处理:在日志系统中,日志请求可能需要经过多个处理步骤,如日志过滤、日志格式化和日志存储等。责任链模式可以帮助日志请求依次传递给各个处理器,直到处理完成。
事务处理:在大型的业务系统中,事务的处理可能需要经过多个阶段,每个阶段负责不同的处理逻辑(如校验、计算、审批等)。责任链模式能够清晰地组织事务的处理流程,确保每个阶段按顺序执行。
事件处理:在用户界面中,用户的操作(如点击按钮、拖动鼠标等)可能会触发多个事件监听器。责任链模式可以将这些事件传递给不同的监听器,让它们依次处理,不同的监听器只负责处理自己关心的部分。
总结:
责任链模式通过将多个处理者连接成链条,使得请求可以沿链条传递,直到被某个处理者处理。它帮助我们减少了代码中的耦合性,每个处理者只关心自己职责范围内的请求,避免了请求对象对处理者的直接依赖。这种模式适合用于多级处理场景,能够清晰、高效地组织请求处理流程。