设计模式|职责链模式--流程状态审批(枚举实现)

流程审批

       在实际的项目中,我们经常会涉及到某个对象实体的状态转换,比如合同审批,请假审批,订单流程状态流转,由于本文不涉及工作流(Activiti,Zeebe)的介绍,只是介绍职责链模式的设计模式,因此我们只涉及状态的简单变更。

场景描述

       张总是一家大型电商公司的老总,每天都会有很多店铺,零售合同等着他审批,在审批之前他都会先经过法务、财务等部门主管的审批,基本过程为:跟进人添加合同相关字段数据,合同状态为待提交,等跟进人确认提交了合同后,合同变为待审核,若被取消,则变为已取消;接着由多级部门审批,审批通过为待签署,若被驳回,则变回为待审核状态,若签署过后,则为已完成,若合同不续约,则为已终止

       上面场景的描述,可能比较拗口,我将他们的状态流转画成流程图,看下方:

设计模式|职责链模式--流程状态审批(枚举实现)_第1张图片       我们在做页面交互的时候,其实对应着按钮也有几个状态,我们需要对应按钮的状态来判断当前用户执行的操作,为此我们也需要按钮的拒绝、确认、作废三个状态。

具体代码

       职责链的核心思想是,把代码串成一条完整的调用链条,我们在平时的业务开发中,经常涉及处理过程,有了职责链模式,我们可以随时增加或修改一个请求的结构,增强了对象指派的灵活性,但要注意的是,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确的配置而得不到处理,因此需要做一些极端情况的处理。

       ButtonStatus.java

/**
 * 合同审批场景:合同新建
 * @author dzx 
 * @since 2020/5/8
 */
public enum  ButtonStatus {
     
    /**
     * 拒绝
     */
    REJECT,
    /**
     * 确认
     */
    CONFIRM,
    /**
     * 作废
     */
    VOID
}

       ContractChainStatus .java

/**
 * Description:
 * 

* 合同状态 *

* @author dzx * @date 2020/5/8 20:56 */
public enum ContractChainStatus { /** * 待提交 */ TO_BE_SUBMIT{ @Override public ContractChainStatus nextStatus(){ return TO_BE_AUDIT; } @Override public ContractChainStatus voidStatus(){ return CANCEL; } }, /** * 待审核 */ TO_BE_AUDIT{ @Override public ContractChainStatus nextStatus() { return TO_BE_SIGN; } @Override public ContractChainStatus preStatus() { return TO_BE_SUBMIT; } }, /** * 待签署 */ TO_BE_SIGN{ @Override public ContractChainStatus nextStatus() { return COMPLETED; } }, /** * 已取消 */ CANCEL, /** * 已完成 */ COMPLETED{ @Override public ContractChainStatus nextStatus() { return TERMINATED; } }, /** * 已终止 */ TERMINATED; //以下方法将被以上的枚举内部类覆盖 public ContractChainStatus nextStatus(){ throw new RuntimeException("没有下一个状态"); } public ContractChainStatus preStatus(){ throw new RuntimeException("前一个状态"); } public ContractChainStatus voidStatus(){ throw new RuntimeException("取消状态"); } }

       可以看出,部分状态才有下一个状态与上一个状态,当没有该状态的时候就会抛出异常,这里使用了枚举特性,巧妙的链式调用了重写方法,具体调用过程:

       ContractChainStatus .java

/**
     * 获取相关合同状态节点
     * @param auditStatus 操作状态
     * @param contractStatus 合同状态
     * @exception ContractException 业务异常,此处为自定义业务异常
     * @return ContractStatus 合同状态枚举
     */
    public ContractStatus getContractStatus(ButtonStatus buttonStatus ,ContractStatus contractStatus) throws ContractException{
     
        switch (buttonStatus){
     
            //前端接收状态:确认
            case CONFIRM:
                return contractStatus.nextStatus();
            //前端接收状态:拒绝
            case REJECT:
                return contractStatus.preStatus();
                //前端接收状态:作废
            case VOID:
                return contractStatus.voidStatus();
            default:
                //500204104表业务编码,抛出业务异常
                throw new ContractException(500204104, "当前审批节点不允许该操作");
        }
    }

你可能感兴趣的:(分布式,java,设计模式)