从分治思维谈”责任链模式“(含源码下载)

2022-10-28 14:24:37 浏览数 (1)

概述

作者前段时间有写过一篇文章:原来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复制
部门经理;已经处理,流程结束

本文完!

0 人点赞