职责链模式
文章目录
1.职责链模式
责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。
1.介绍
意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求进行处理,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
主要解决:一个事件需要经过多个对象处理是很常见的场景。
关键代码:Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。
2.应用实例
现实中,请假的OA申请:
请假天数如果是1天,可能直接主管批准即可;
如果是1到7天的假期,需要部门经理批准;
如果是7天到30天,则需要总经理审批;
大于30天,正常不会批准
优点: 1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。
缺点: 1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
代码
为了实现上述场景,我们可以采用责任链设计模式。
- 员工请假请求类:LeaveRequest。
- 抽象的请假责任处理类:AbstractLeaveHandler。
- 直接主管审批处理类:DirectLeaderHandler。
- 部门经理处理类:DepartmentManagerHandler。
- 总经理处理类: CompanyManagerHandler。
1.员工提交请求类:LeaveRequest
package com.jzj.design.demo.responsibilityDesign;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 请假请求封装
*/
@Data
@NoArgsConstructor
public class LeaveRequest {
/**
* 员工编号
*/
private String employeeId;
/**
* 员工姓名
*/
private String employeeName;
/**
* 员工请假天数
*/
private Integer leaveDays;
public LeaveRequest(String employeeId, String employeeName, Integer leaveDays) {
this.employeeId = employeeId;
this.employeeName = employeeName;
this.leaveDays = leaveDays;
System.out.println("员工:"+employeeId+" 姓名:"+employeeName+" 申请请假 "+leaveDays+" 天");
}
}
2. 抽象请假处理类:AbstractLeaveHandler
AbstractLeaveHandler 中定义了2个抽象方法
- public abstract String getApproveName(); 设置审批人名字,由子类去具体实现
- public abstract Integer getLimitDays(); 设置审批人可以处理的天数,由子类去具体实现
package com.jzj.design.demo.responsibilityDesign;
/**
* 抽象的责任链处理类
*/
public abstract class AbstractLeaveHandler {
/**
* !!!!! 定义下一个处理节点
*/
private AbstractLeaveHandler nextHandler;
/**
* 设置下一个 处理节点
*
* @param nextHandler
*/
public void setNextHandler(AbstractLeaveHandler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 抽象类 ->审批人名字; 由子类去实现
*/
public abstract String getApproveName();
/**
* 抽象类-> 由子类去设置 每一个审批人 可以处理 处理的请假天数
*/
public abstract Integer getLimitDays();
/**
* 处理请假请求, 由他的子类来实现
*
* @param leaveRequest
*/
public void handlerLeaveRequest(LeaveRequest leaveRequest) {
//如果 权限限制的天数 > 请假的天数,说明由权限审批
if (getLimitDays() >= leaveRequest.getLeaveDays()) {
System.out.println("当前处理人" + getApproveName() + " 同意 请假请求");
} else if (this.nextHandler != null) {
//依旧有人可以处理审批
this.nextHandler.handlerLeaveRequest(leaveRequest);
} else {
System.out.println("没有人------ 能够同意 请假请求!!");
}
}
}
3.直接主管审批处理类:DirectLeaderHandler
直接主管处理类,继承抽象类 AbstractLeaveHandler,实现他的方法去自定义 可以处理天数LimitDays 1天 及审批人名字ApproveName
package com.jzj.design.demo.responsibilityDesign;
/**
* 直接主管
*/
public class DirectLeaderHandler extends AbstractLeaveHandler{
@Override
public Integer getLimitDays() {
//直接主管 只能审批 1 天内的请假
return 1;
}
@Override
public String getApproveName() {
return "直接主管-白毛女";
}
}
4.部门经理处理类:DepartmentManagerHandler
部门经理处理类,继承抽象类 AbstractLeaveHandler,实现他的方法去自定义 可以处理天数LimitDays 7天及审批人名字
package com.jzj.design.demo.responsibilityDesign;
/**
* 部门经理
*/
public class DepartmentManagerHandler extends AbstractLeaveHandler{
@Override
public Integer getLimitDays() {
//部门经理 只能审批 7 天内的请假
return 7;
}
@Override
public String getApproveName() {
return "部门经理-杨白劳";
}
}
5.总经理处理类: CompanyManagerHandler
公司总经理处理类,继承抽象类 AbstractLeaveHandler,实现他的方法去自定义 可以处理天数LimitDays 30天及审批人名字
package com.jzj.design.demo.responsibilityDesign;
/**
* 公司总经理
*/
public class CompanyManagerHandler extends AbstractLeaveHandler{
@Override
public Integer getLimitDays() {
//公司总经理 只能审批 30 天内的请假
return 30;
}
@Override
public String getApproveName() {
return "公司总经理-黄世仁";
}
}
结果
我们设置调用链 directManager直接主管-next-> departMentManager 部门经理-next-> companyManager 公司总经理
- directManagerHandler.setNextHandler(departMentManager);
- departMentManager.setNextHandler(companyManager);
package com.jzj.design.demo.responsibilityDesign;
public class LeaveMain {
public static void main(String[] args) {
AbstractLeaveHandler directManagerHandler = new DirectLeaderHandler();
AbstractLeaveHandler departMentManager = new DepartmentManagerHandler();
AbstractLeaveHandler companyManager = new CompanyManagerHandler();
directManagerHandler.setNextHandler(departMentManager);
departMentManager.setNextHandler(companyManager);
LeaveRequest leaveRequest1 = new LeaveRequest("1", "a", 1);
directManagerHandler.handlerLeaveRequest(leaveRequest1);
System.out.println("==============================================================");
LeaveRequest leaveRequest5 = new LeaveRequest("5", "b", 5);
directManagerHandler.handlerLeaveRequest(leaveRequest5);
System.out.println("==============================================================");
LeaveRequest leaveRequest20 = new LeaveRequest("20", "c", 20);
directManagerHandler.handlerLeaveRequest(leaveRequest20);
System.out.println("==============================================================");
LeaveRequest leaveRequest40 = new LeaveRequest("40", "d", 40);
directManagerHandler.handlerLeaveRequest(leaveRequest40);
}
}
可以看到结果
1天的请假、直接主管直接审批
5 天的请假、部门经理审批
20天的请假、公司总经理审批
40天的请假、没有人审批通过