责任链设计模式
概念
责任链(chain of responsibility)模式很像异常的捕获和处理,当一个问题发生的时候,当前对象看一下自己是否能够处理,不能的话将问题抛给自己的上级去处理,但是要注意这里的上级不一定指的是继承关系的父类,这点和异常的处理是不一样的。所以可以这样说,当问题不能解决的时候,将问题交给另一个对象去处理,就这样一直传递下去直至当前对象找不到下线了,处理结束。如下图所示,处于同等层次的类都继承自LeaveProcess类,当当前对象不能处理的时候,会根据预先设定好的传递关系将问题交给下一个人,可以说是“近水楼台先得月”,就看有没有能力了。我们也可以看作是大家在玩一个传谜语猜谜底的小游戏,按照座位的次序以及规定的顺序传递,如果一个人能回答的上来游戏就结束,否则继续向下传,如果所有人都回答不出来也会结束。这样或许才是责任链的本质,体现出了同等级的概念。
场景
请假模型:请假条先递交给组长,组长只有处理两天请假权限,如果超出递交给部门领导处理,部门领导只有处理五天的权限,超出权限递交给公司领导处理
利用责任链设计模式实现
假条模型
public class LeaveRequisition {
private String name;
private String deptName;
private Integer days;
public LeaveRequisition(String name, String deptName, Integer days) {
this.name = name;
this.deptName = deptName;
this.days = days;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public Integer getDays() {
return days;
}
public void setDays(Integer days) {
this.days = days;
}
}
请假处理器接口
public interface LeaveProcess {
void process(LeaveRequisition leaveRequisition);
}
各种请假处理器实现
小组领导
public class GroupLeaderProcess implements LeaveProcess {
private LeaveProcess nextProcess;
public GroupLeaderProcess() {
}
public GroupLeaderProcess(LeaveProcess nextProcess) {
this.nextProcess = nextProcess;
}
public void process(LeaveRequisition leaveRequisition) {
if (leaveRequisition.getDays()> 2){
System.out.println("小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批");
nextProcess.process(leaveRequisition);
return;
}
System.out.println("请假批准,"+leaveRequisition.getDays()+"后快去快回");
}
}
部门领导
public class DepartmentLeader implements LeaveProcess {
private LeaveProcess nextProcess;
public DepartmentLeader() {
}
public DepartmentLeader(LeaveProcess nextProcess) {
this.nextProcess = nextProcess;
}
public void process(LeaveRequisition leaveRequisition) {
if (leaveRequisition.getDays()> 5){
System.out.println("部门经理只有审批五天的请假权限,该申请超过五天,移交给公司领导审批");
nextProcess.process(leaveRequisition);
return;
}
System.out.println("请假批准,"+leaveRequisition.getDays()+"后快去快回");
}
}
公司领导
public class CompanyProcess implements LeaveProcess {
private LeaveProcess nextProcess;
public CompanyProcess() {
}
public CompanyProcess(LeaveProcess nextProcess) {
this.nextProcess = nextProcess;
}
public void process(LeaveRequisition leaveRequisition) {
System.out.println("请假批准,"+leaveRequisition.getDays()+"后快去快回");
}
}
测试类
public class TestProcess {
public static void main(String[] args) {
// 创建请假条
LeaveRequisition leaveRequisition = new LeaveRequisition("zhansan", "dev", 9);
// 构建责任链
LeaveProcess leaveProcess = new GroupLeaderProcess(new DepartmentLeader(new CompanyProcess()));
// 提交请假申请
leaveProcess.process(leaveRequisition);
}
}
运行结果
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
部门经理只有审批五天的请假权限,该申请超过五天,移交给公司领导审批
请假批准,9后快去快回
责任链设计模式优化
该模式存在一个问题,当业务的吞吐量很大的时候,每次移交必须等到下一级别的返回才算结束,其实在我们提交申请之后是不关心请假到底是否被批准,只是过会过来看一下结果就好,所以我们就可以采用一个阻塞 队列,每次提交i只是放到下一级审批人的阻塞队列中,审批人自己 去取就好了,这就是一个典型的生产者消费这模式,java回我们提供了很多阻塞队列,我们就可以基于这种思想去对这个请假的责任链进行优化
优化代码如下
private LeaveProcess nextProcess;
// 存放请假消息
private LinkedBlockingQueue<LeaveRequisition> leaveRequisitions = new LinkedBlockingQueue<LeaveRequisition>();
// 用判断是否结束
private boolean isFinish = false;
public GroupLeaderProcess() {
}
public GroupLeaderProcess(LeaveProcess nextProcess) {
this.nextProcess = nextProcess;
}
@Override
public void run() {
while (!isFinish){
try {
// 消费者
LeaveRequisition leaveRequisition = leaveRequisitions.take();
if (leaveRequisition.getDays()> 2){
System.out.println("小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批");
nextProcess.process(leaveRequisition);
continue;
}
System.out.println("请假批准,"+leaveRequisition.getDays()+"后快去快回");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 生产者
public void process(LeaveRequisition leaveRequisition) {
leaveRequisitions.add(leaveRequisition);
}
}
这里只贴出小组处理,其他的也一样
测试
public class TestProcess {
public static void main(String[] args) {
CompanyProcess companyProcess = new CompanyProcess();
companyProcess.start();
DepartmentLeader departmentLeader = new DepartmentLeader(companyProcess);
departmentLeader.start();
// 构建责任链
GroupLeaderProcess groupLeaderProcess = new GroupLeaderProcess(departmentLeader);
groupLeaderProcess.start();
// 提交请假申请
for (int i = 0; i < 10; i++) {
// 创建请假条
LeaveRequisition leaveRequisition = new LeaveRequisition("zhansan", "dev", i);
groupLeaderProcess.process(leaveRequisition);
}
}
}
测试结果
请假批准,0后快去快回
请假批准,1后快去快回
请假批准,2后快去快回
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
请假批准,3后快去快回
请假批准,4后快去快回
请假批准,5后快去快回
小组主管只有审批五天的请假权限,该申请超过五天,移交给公司经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批五天的请假权限,该申请超过五天,移交给公司经理审批
小组主管只有审批五天的请假权限,该申请超过五天,移交给公司经理审批
小组主管只有审批五天的请假权限,该申请超过五天,移交给公司经理审批
请假批准,6后快去快回
请假批准,7后快去快回
请假批准,8后快去快回
请假批准,9后快去快回
结束语
有何不对谢谢指正,走在BAT的路上,我们一起进步