责任链模式多级审批

一、概念理解

1、责任链模式

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

2、责任链模式的结构

  • Handler(处理者):定义一个处理请求的接口。通常包含一个处理请求的方法(如 handleRequest)和一个设置后继者的方法(如 setNext)。
  • ConcreteHandler(具体处理者):实现 Handler 接口,处理它所负责的请求。可以访问它的后继者以便在自己无法处理该请求时将其传递下去。
  • Client(客户端):向链上的具体处理者对象提交请求。

3、责任链模式的优点

  • 降低耦合度:请求的发送者和接收者解耦,发送者不需要知道是哪一个接收者处理了请求。
  • 增加灵活性:可以动态地新增或删除责任链上的处理者,修改处理者的顺序等。
  • 增强可扩展性:通过添加新的具体处理者类,扩展系统的功能。

4、责任链模式的缺点

  • 不保证请求一定会被处理:如果链的末尾没有处理请求,可能会导致请求被忽略。
  • 调试困难:由于请求的处理是沿着链进行的,调试过程可能较为复杂。

二、代码案例

不同请假天数需要不同级别人员审核,所以将不同处理类定义成一个责任链

1、责任链执行抽象类

编写过滤责任链执行抽象类AbstractExecuteFilter.java

public abstract class AbstractExecuteFilter {
    //ThreadLocal存储key
    public static final String SLOT_KEY = "LeaveRequest";
    //下一个拦截
    protected AbstractExecuteFilter nextFilter;
    //存储参数
    public static ThreadLocal<Map<String, Object>> localMap = new ThreadLocal<>();
    public void addNextFilter(AbstractExecuteFilter filter) {
        this.nextFilter = filter;
    }
    public abstract boolean execute();
    /**直接主管审批处理的请假天数*/
    protected int MIN = 1;
    /**部门经理处理的请假天数*/
    protected int MIDDLE = 3;
    /**总经理处理的请假天数*/
    protected int MAX = 30;
}

编写参数传递类(请假类):

@Builder
public class LeaveRequest {
    /**天数*/
    private int leaveDays;
    /**姓名*/
    private String name;
}

2、设置上下文环境获取bean

根据不同的filters名动态获取对象,ExecuteFilterLoader实现ApplicationContextAware接口,

@Slf4j
@Component
public class ExecuteFilterLoader implements ApplicationContextAware {

    public static ApplicationContext applicationContext;
    /**
     * 加载规则执行链
     * 实现ApplicationContextAware接口的回调方法,设置上下文环境
     * @param applicationContext spring上下文对象
     * @throws BeansException 抛出spring异常
     */
    public static AbstractExecuteFilter loadExecuteFilter(List<String> filters) {
        if (CollectionUtils.isEmpty(filters)) {
            throw BusinessException.asBusinessException(BusinessErrorCode.ILLEGAL_ARG_ERROR);
        }
        AbstractExecuteFilter filter = null;
        AbstractExecuteFilter next = null;
        for (String filterName : filters) {
            AbstractExecuteFilter bean = (AbstractExecuteFilter) applicationContext.getBean(filterName);
            if (null == next) {
                filter = bean;
            } else {
                next.addNextFilter(bean);
            }
            next = bean;
        }
        return filter;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ExecuteFilterLoader.applicationContext = applicationContext;
    }
}

3、不同处理类扩展 AbstractLeaveHandler

创建三种类型的审批处理,都继承了 AbstractLeaveHandler抽象类:

/**
* 直接领导处理
*/
@Slf4j
@Component("directLeaderLeaveHandler")
public class DirectLeaderLeaveHandler extends AbstractLeaveHandler {
    @Override
    public void execute() {
        int leaveDays = (int) localMap.get().get("leaveDays");
        if(leaveDays <= this.MIN){
            System.out.println("直接主管已经处理;流程结束。");
            return;
        }
        if(null != this.nextFilter){
            this.nextFilter.execute();
        }else{
            System.out.println("审批拒绝!");
        }
    }
}

/**
* 部门领导处理
*/
@Slf4j
@Component("deptManagerLeaveHandler")
public class DeptManagerLeaveHandler extends AbstractLeaveHandler {
    @Override
    public void execute() {
        int leaveDays = (int) localMap.get().get("leaveDays");
        if(leaveDays >this.MIN && leaveDays <= this.MIDDLE){
            System.out.println("部门经理已经处理;流程结束。");
            return;
        }
        if(null != this.nextFilter){
            this.nextFilter.execute();
        }else{
            System.out.println("审批拒绝!");
        }
    }
}



/**
* 总经理处理
*/
@Slf4j
@Component("gManagerLeaveHandler")
public class GManagerLeaveHandler extends AbstractLeaveHandler {
    @Override
    public void execute() {
        int leaveDays = (int) localMap.get().get("leaveDays");
        if(leaveDays > this.MIDDLE && leaveDays <= this.MAX){
            System.out.println("总经理已经处理;流程结束。");
            return;
        }
        if(null != this.nextFilter){
            this.nextFilter.execute();
        }else{
            System.out.println("审批拒绝!");
        }
    }
}

4、调用

(新员工请假20天谁审批):

//要处理的责任链(直接领导、部门领导、总经理审批)
String filterConfig="directLeaderLeaveHandler,deptManagerLeaveHandler,gManagerLeaveHandler";
//入参
LeaveRequest request = LeaveRequest.builder().leaveDays(20).name("新员工").build();
//不同责任链类间通过ThreadLocal参数传递
Map<String, Object> localMap = new HashMap<>();
localMap.put(AbstractExecuteFilter.SLOT_KEY,request);
AbstractExecuteFilter.localMap.set(localMap);//传递参数
ExecuteFilterLoader.loadExecuteFilter(Arrays.asList(filterConfig.split(","))).execute();

运行结果:总经理已经处理;流程结束。

小结:调用了审批链不同环节的处理,应用责任链模式进行解耦,增强给对象指派职责的灵活性。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只IT攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值