概述
作者前段时间有写过一篇文章:原来Unix设计实现正是这种思想应用的典范!
主要演示的是“管道模式”的核心思想及应用场景,也附上了相关源码,有兴趣的小伙伴可以下载查看。
今天跟大家分享的这篇文章算是姊妹篇,标题为:”从分治思想谈责任链模式“。
为什么说它是姊妹篇呢?
因为其实他们都是“分治”思想的体现。即一口大饼吃不成一个胖子吧,所以我们吃东西需要一口一口吃。这就是分的思想。
“管道模式” 讲究的是每一个阀门处理其中一部分数据,然后流转到下一个节点处理另一部分数据,知道尾节点把事情处理完成。
“责任链模式”不同。体现在它不需要每一个处理器都需要处理,如果中间有一个节点,能把事情给处理了,那流程就正常结束。
这种思想,被大量应用在”工作流“或“规则引擎中”。
应用场景
拿请假审批这件事情来说,我来举个例子:
比如小明同学家里有事,需要提前向公司提交请教申请。一般公司都会有相应软件吧。
那界面上势必会让他填写请假”开始时间-结束时间“吧。
系统会根据他提交的天数,生成一个链路,比如如果1天,可能直接流转到部门主管审批,审批完成后,就结束 。
如果他提交的请假天数,比较多,比如请产假或婚假。那可能除了部门主管,还需要总监、总经理。
每一个处理器审批的逻辑很简单,会根据审批天数及上下节点的处理状态,进行流转。
可能先流转到“部门主管”,部门主管处理完意见后。会流转到总监。总监处理完后,最后会流转到”总经理“,让总经理进行审批。总经理审批完后流程结束。
代码演示
接下来我用JAVA代码简单模拟一个请假业务场景,用”责任链模式“是实现,大家可以看下。
1)我们先定义一个抽象类
在成员变量中简单标识一下请假天数边界。比如小于等于1天即实际提交天数小于等于MIN,那部门经理需要审批。依次类推...
最后一个抽象方法handlerRequest需要每个子类自己实现。因为处理逻辑都不一样。
代码语言:javascript复制public abstract class AbstractLeaveHandler {
/**
* 直接主管审批处理的请假天数
*/
protected int MIN=1;
/**
* 部门经理处理的请假天数
*/
protected int MIDDLE=7;
/**
* 总经理处理的请假天数
*/
protected int MAX=30;
/**
* 领导名称
*/
protected String handlerName;
/**
* 下一个处理节点
*/
protected AbstractLeaveHandler nextHandler;
protected void setNextHandler(AbstractLeaveHandler handler){
this.nextHandler=handler;
}
protected abstract void handlerRequest(LeaveRequest request);
}
2)定义抽象类的子类
直接主管
代码语言:javascript复制public class DirectLeaderLeveHandler extends AbstractLeaveHandler{
public DirectLeaderLeveHandler(String name){
this.handlerName=name;
}
@Override
protected void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays()<=this.MIN){
System.out.println(handlerName ";已经处理,流程结束");
return;
}
if(null!=nextHandler){
this.nextHandler.handlerRequest(request);
}else {
System.out.println("审批拒绝!");
}
}
}
部门主管
代码语言:javascript复制public class DeptManagerLeveHandler extends AbstractLeaveHandler{
public DeptManagerLeveHandler(String name){
this.handlerName=name;
}
@Override
protected void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays()>this.MIN && request.getLeaveDays()<=this.MIDDLE){
System.out.println(handlerName ";已经处理,流程结束");
return;
}
if(null!=nextHandler){
this.nextHandler.handlerRequest(request);
}else {
System.out.println("审批拒绝!");
}
}
}
总经理
代码语言:javascript复制public class GManagerLeveHandler extends AbstractLeaveHandler{
public GManagerLeveHandler(String name){
this.handlerName=name;
}
@Override
protected void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays()>this.MIDDLE && request.getLeaveDays()<=this.MAX){
System.out.println(handlerName ";已经处理,流程结束");
return;
}
if(null!=nextHandler){
this.nextHandler.handlerRequest(request);
}else {
System.out.println("审批拒绝!");
}
}
}
有一个入参DTO
代码语言:javascript复制@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LeaveRequest {
/**
* 天数
*/
private int leaveDays;
/**
* 姓名
*/
private String name;
}
最后写一个本地单测
代码语言:javascript复制public class ResponsibilityChainTest {
public static void main(String[] args) {
LeaveRequest request=LeaveRequest.builder().leaveDays(6).name("小明").build();
AbstractLeaveHandler directLeaver=new DirectLeaderLeveHandler("直接主管");
AbstractLeaveHandler deptManager=new DeptManagerLeveHandler("部门经理");
AbstractLeaveHandler gManager=new GManagerLeveHandler("总经理");
directLeaver.setNextHandler(deptManager);
deptManager.setNextHandler(gManager);
directLeaver.handlerRequest(request);
}
}
输出:
代码语言:javascript复制部门经理;已经处理,流程结束
本文完!