责任链模式 Chain of Responsibility
1 意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
2 结构
-
Handler 定义一个处理请求的接口;(可选)实现后继链。
-
ConcreteHandler 处理它所负责的请求;可访问它的后继者;如果可处理该请求理它,否则将该请求转发给后继者。
-
Client 向链上的具体处理者**(ConcreteHandler)**对象提交请求。
3 适用性
Chain ofResponsibility 模式适用于以下条件:
-
有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
-
想在不明确指定接收者的情况下向多个对象中的一个提交一个请求。
-
可处理一个请求的对象集合应被动态指定。
4 应用举例
1 应用案例:请假审批流程
假设在一个公司中,员工请假需要经过不同级别的审批,例如,1天以内的请假由直接上级批准,2天到5天的请假由部门经理批准,超过5天的请假由人力资源部批准。我们可以使用责任链模式来实现这样的审批流程。
Java代码示例:
// 抽象处理者
abstract class LeaveApprover {
protected LeaveApprover nextApprover; // 后继处理者
public void setNextApprover(LeaveApprover nextApprover) {
this.nextApprover = nextApprover;
}
// 审批请假
public abstract void processRequest(int leaveDays);
}
// 直接上级
class DirectSupervisor extends LeaveApprover {
@Override
public void processRequest(int leaveDays) {
if (leaveDays <= 1) {
System.out.println("直接上级批准了 " + leaveDays + " 天的请假。");
} else {
if (nextApprover != null) {
nextApprover.processRequest(leaveDays);
} else {
System.out.println("没有后续处理者,无法审批超过 " + leaveDays + " 天的请假。");
}
}
}
}
// 部门经理
class DepartmentManager extends LeaveApprover {
@Override
public void processRequest(int leaveDays) {
if (leaveDays <= 5) {
System.out.println("部门经理批准了 " + leaveDays + " 天的请假。");
} else {
if (nextApprover != null) {
nextApprover.processRequest(leaveDays);
} else {
System.out.println("没有后续处理者,无法审批超过 " + leaveDays + " 天的请假。");
}
}
}
}
// 人力资源部
class HRDepartment extends LeaveApprover {
@Override
public void processRequest(int leaveDays) {
System.out.println("人力资源部批准了 " + leaveDays + " 天的请假。");
}
}
public class ChainOfResponsibilityDemo {
public static void main(String[] args) {
LeaveApprover directSupervisor = new DirectSupervisor();
LeaveApprover departmentManager = new DepartmentManager();
LeaveApprover hrDepartment = new HRDepartment();
// 构建责任链
directSupervisor.setNextApprover(departmentManager);
departmentManager.setNextApprover(hrDepartment);
// 提交请假申请
int leaveDays = 3;
directSupervisor.processRequest(leaveDays); // 将请求发送给直接上级
leaveDays = 7;
directSupervisor.processRequest(leaveDays); // 再次提交更长时间的请假申请
}
}
在这个例子中:
LeaveApprover
是抽象处理者,定义了处理请求的接口。DirectSupervisor
,DepartmentManager
,HRDepartment
分别是具体处理者,每个处理者都有自己的判断逻辑,如果当前处理者不能处理请求,则会将其传递给下一个处理者。
通过责任链模式,我们可以灵活地添加、删除或修改处理者,而不影响其他部分的代码,这使得系统具有更好的扩展性和维护性。