责任链模式 (Chain of Responsibility Pattern)
责任链模式是一种行为型设计模式,它允许将请求沿着一条链传递,直到链上的某个对象处理该请求。每个处理者都持有对下一个处理者的引用,若当前处理者无法处理该请求,则将其传递给下一个处理者。责任链模式的关键思想是:将请求的发送者和接收者解耦,使得多个对象有机会处理请求,避免请求的发送者与接收者之间的直接关联。
1. 责任链模式的组成
责任链模式包含以下几个主要角色:
- Handler(处理者接口):定义了处理请求的接口,通常包含一个
handleRequest()方法,并有一个对下一个处理者的引用。 - ConcreteHandler(具体处理者):实现了
Handler接口,并定义了处理请求的具体行为。如果该处理者无法处理请求,则将请求传递给下一个处理者。 - Client(客户端):客户端通过创建处理链并发送请求来触发处理链的执行。
2. 责任链模式的工作流程
- 客户端创建一个请求对象,并将请求传递给责任链的第一个处理者。
- 处理者尝试处理请求。如果它能处理请求,则完成请求的处理;否则,它将请求传递给链中的下一个处理者。
- 请求继续沿链传递,直到找到一个可以处理请求的处理者,或者请求最终被丢弃(如果没有处理者能够处理该请求)。
3. 责任链模式的实现
场景示例:审批流程
假设一个公司有不同级别的经理,每个经理可以审批一定金额范围内的费用。我们可以通过责任链模式来处理费用审批请求,不同级别的经理会根据自己能审批的额度来处理请求。
1) 定义处理者接口
Handler接口定义了一个处理请求的方法handleRequest(),并包含一个指向下一个处理者的引用。
// 处理者接口
public abstract class Approver {
protected Approver nextApprover;
public void setNextApprover(Approver nextApprover) {
this.nextApprover = nextApprover;
}
public abstract void handleRequest(Request request);
}
2) 定义请求类
请求类包含请求的具体内容,例如费用的金额和请求者的信息。
// 请求类
public class Request {
private String requestor;
private double amount;
public Request(String requestor, double amount) {
this.requestor = requestor;
this.amount = amount;
}
public String getRequestor() {
return requestor;
}
public double getAmount() {
return amount;
}
}
3) 定义具体处理者类
每个具体的处理者类会处理请求,如果它不能处理请求,则会将请求传递给下一个处理者。
// 部门经理
public class DepartmentManager extends Approver {
@Override
public void handleRequest(Request request) {
if (request.getAmount() <= 1000) {
System.out.println("部门经理审批通过:请求人:" + request.getRequestor() + ",金额:" + request.getAmount());
} else if (nextApprover != null) {
nextApprover.handleRequest(request); // 将请求传递给下一个处理者
}
}
}
// 总经理
public class GeneralManager extends Approver {
@Override
public void handleRequest(Request request) {
if (request.getAmount() <= 5000) {
System.out.println("总经理审批通过:请求人:" + request.getRequestor() + ",金额:" + request.getAmount());
} else if (nextApprover != null) {
nextApprover.handleRequest(request); // 将请求传递给下一个处理者
}
}
}
// CEO
public class CEO extends Approver {
@Override
public void handleRequest(Request request) {
if (request.getAmount() > 5000) {
System.out.println("CEO审批通过:请求人:" + request.getRequestor() + ",金额:" + request.getAmount());
} else if (nextApprover != null) {
nextApprover.handleRequest(request); // 将请求传递给下一个处理者
}
}
}
4) 客户端代码
客户端代码负责创建责任链,并发送请求到责任链的第一个处理者。
public class Client {
public static void main(String[] args) {
// 创建具体处理者
Approver departmentManager = new DepartmentManager();
Approver generalManager = new GeneralManager();
Approver ceo = new CEO();
// 设置责任链的顺序
departmentManager.setNextApprover(generalManager);
generalManager.setNextApprover(ceo);
// 客户端请求
Request request1 = new Request("张三", 800);
departmentManager.handleRequest(request1); // 部门经理审批通过
Request request2 = new Request("李四", 3000);
departmentManager.handleRequest(request2); // 总经理审批通过
Request request3 = new Request("王五", 10000);
departmentManager.handleRequest(request3); // CEO审批通过
}
}
运行结果:
部门经理审批通过:请求人:张三,金额:800.0
总经理审批通过:请求人:李四,金额:3000.0
CEO审批通过:请求人:王五,金额:10000.0
4. 责任链模式的优点
- 解耦请求发送者和接收者: 请求的发送者和处理者不再直接依赖,而是通过链传递请求。
- 动态添加或删除处理者: 可以灵活地调整处理者链的顺序,添加或删除处理者,符合开闭原则。
- 提高系统的灵活性: 每个处理者都独立处理请求,系统可以动态地增加或修改处理逻辑,而不影响其他部分。
- 避免使用多重条件语句: 在没有责任链模式的情况下,处理不同情况可能需要写多重条件判断,而责任链模式通过链式结构简化了代码。
5. 责任链模式的缺点
- 请求处理可能被延迟: 如果责任链中的所有处理者都无法处理请求,请求可能被传递到链的最后,导致延迟处理。
- 链的复杂性: 如果链的层级过深,维护和理解责任链可能会变得复杂。
- 可能导致无法预知的行为: 如果某个处理者忽略请求传递给下一个处理者,可能会导致请求的丢失或处理不当。
6. 责任链模式的应用场景
- 审批流程: 如公司内部的费用审批、请假申请等,每个不同层级的人员可以处理不同金额或级别的请求。
- 日志处理: 日志记录系统中的日志可以通过责任链模式传递给不同的日志处理器(如控制台输出、文件写入、数据库存储等)。
- 事件处理: 在GUI框架中,事件的处理可以采用责任链模式,如点击、拖拽等不同事件的处理。
- 责任分配: 比如在任务分配系统中,不同级别的员工处理不同难度的任务时,可以采用责任链模式。
7. 总结
责任链模式通过将请求沿链传递,让多个对象有机会处理请求,避免了请求发送者与接收者的直接耦合。它使得对象的行为更加灵活,并且能够在不修改客户端代码的前提下,动态地改变处理流程。虽然责任链模式提供了更大的灵活性,但在链较长或处理较复杂时,可能导致处理效率降低,因此需要在适当的场景中使用。
557

被折叠的 条评论
为什么被折叠?



