责任链模式 (Chain of Responsibility)
场景问题
问题案例
考虑一个请假审批系统,普通员工请假需要组长审批,组长请假需要经理审批,经理请假需要总监审批。如何灵活扩展审批流程?
不用模式的解决方案
实现简化版本
最直接的做法是用if-else语句判断请假天数,决定由谁审批:
public class LeaveRequest {
private int days;
public LeaveRequest(int days) { this.days = days; }
public int getDays() { return days; }
}
public class Approver {
public void approve(LeaveRequest request) {
if (request.getDays() <= 1) {
System.out.println("组长审批");
} else if (request.getDays() <= 3) {
System.out.println("经理审批");
} else {
System.out.println("总监审批");
}
}
}
使用示例
Approver approver = new Approver();
approver.approve(new LeaveRequest(2));
有何问题
- 审批流程不灵活,扩展困难。
- 违反开闭原则。
- 代码难以维护。
解决方案
责任链模式的定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,请求沿着链传递,直到有对象处理它为止。
应用责任链模式的思路
- 定义抽象处理者,包含处理请求和传递请求的方法。
- 每个具体处理者持有下一个处理者的引用。
- 客户端只需将请求交给链头即可。
责任链模式的结构
- Handler:抽象处理者,定义处理请求和传递请求的方法。
- ConcreteHandlerA/B:具体处理者,实现具体处理逻辑。
责任链模式的实现
// 请求类
public class LeaveRequest {
private int days;
public LeaveRequest(int days) { this.days = days; }
public int getDays() { return days; }
}
// 抽象处理者
public abstract class Approver {
protected Approver next;
public void setNext(Approver next) { this.next = next; }
public abstract void approve(LeaveRequest request);
}
// 具体处理者
public class Leader extends Approver {
public void approve(LeaveRequest request) {
if (request.getDays() <= 1) {
System.out.println("组长审批");
} else if (next != null) {
next.approve(request);
}
}
}
public class Manager extends Approver {
public void approve(LeaveRequest request) {
if (request.getDays() <= 3) {
System.out.println("经理审批");
} else if (next != null) {
next.approve(request);
}
}
}
public class Director extends Approver {
public void approve(LeaveRequest request) {
System.out.println("总监审批");
}
}
使用示例
public class Client {
public static void main(String[] args) {
Approver leader = new Leader();
Approver manager = new Manager();
Approver director = new Director();
leader.setNext(manager);
manager.setNext(director);
leader.approve(new LeaveRequest(2));
leader.approve(new LeaveRequest(4));
}
}
责任链重写示例
示例结构
示例代码
见上文"责任链模式的实现"部分。
模式讲解
责任链模式的功能
- 动态组合处理链,扩展灵活。
- 解耦请求发送者和处理者。
- 满足开闭原则。
实现成接口
- 处理者通常定义为接口或抽象类。
使用工厂方法
- 可结合工厂方法模式,统一创建处理链。
切换产品簇
- 可用于切换不同的处理链,如不同审批流程。