枚举简易实现一个实用审核机制状态机

2023-09-02 10:12:42 浏览数 (2)

在项目中经常会开发的功能,状态审批,在实际项目的开发中,发现很多人都是混合在业务代码中写死的方式去判断更新审核状态,后期维护会出现无法快速有效的整理每个状态前后节点之间的关系.跟业务代码耦合性太高,本篇以解耦和清晰的方式通过枚举方式实现一个简易易用的状态机

枚举代码块

  1. 所有的状态以及审核机制都维护在一个枚举类中,方便理解和维护
  2. 每一个枚举节点中维护了nextState()(通过状态)下一个节点,和rejectState()(拒绝状态)后返回上一个节点的关系维护
  3. currentStatus维护当前节点
  4. statusName维护当前节点名称
代码语言:javascript复制

/**
 * 状态机
 */
public enum StateEnum {

    /**
     * 未提交
     */
    UnSubmitted {
        @Override
        public StateEnum nextState() {
            //已提交 待生效
            return Submitted_WaitActive;
        }

        @Override
        public int currentStatus() {
            return 0;
        }

        @Override
        public String statusName() {
            return "未提交";
        }

        @Override
        public StateEnum rejectState() {
            throw new Exception("状态异常");
        }

    },
    /**
     * 已提交 待生效
     */
    Submitted_WaitActive {
        @Override
        public StateEnum nextState() {
            return Submitted_TaskActive;
        }

        @Override
        public int currentStatus() {
            return 1;
        }

        @Override
        public String statusName() {
            return "待生效审批";
        }

        @Override
        public StateEnum rejectState() {
            return Submitted_Reject;
        }
    },

    /**
     * 已生效
     */
    Submitted_TaskActive {
        @Override
        public StateEnum nextState() {
            //作废
            return Invalid_Wait;
        }

        @Override
        public int currentStatus() {
            return 2;
        }

        @Override
        public String statusName() {
            return "已生效";
        }

        @Override
        public StateEnum rejectState() {
            throw new Exception("状态异常");
        }
    },

    /**
     * 审批拒绝,未生效
     */
    Submitted_Reject {
        @Override
        public StateEnum nextState() {
            //未生效可重新审批到达待审批
            return Submitted_WaitActive;
        }

        @Override
        public int currentStatus() {
            return 3;
        }


        @Override
        public String statusName() {
            return "未生效";
        }

        @Override
        public StateEnum rejectState() {
            return Submitted_Reject;
        }
    },

    /**
     * 待作废审批
     */
    Invalid_Wait {
        @Override
        public StateEnum nextState() {
            //未生效可重新审批到达已作废
            return Invalid_TaskActive;
        }

        @Override
        public int currentStatus() {
            return 4;
        }


        @Override
        public String statusName() {
            return "待作废审批";
        }

        @Override
        public StateEnum rejectState() {
            return Invalid_Reject;
        }
    },

    /**
     * 已作废
     */
    Invalid_TaskActive {
        @Override
        public StateEnum nextState() {
            return Submitted_WaitActive;
        }

        @Override
        public int currentStatus() {
            return 5;
        }


        @Override
        public String statusName() {
            return "已作废";
        }

        @Override
        public StateEnum rejectState() {
            throw new Exception("状态异常");
        }
    },

    /**
     * 作废不通过
     */
    Invalid_Reject {
        @Override
        public StateEnum nextState() {
            //未生效可重新审批到达生效节点
            return Invalid_Wait;
        }

        @Override
        public int currentStatus() {
            return 6;
        }

        @Override
        public String statusName() {
            return "作废不通过";
        }

        @Override
        public StateEnum rejectState() {
            return Invalid_Reject;
        }
    };

    public static StateEnum get(int status){
        for (StateEnum stateEnum : StateEnum.values()) {
            if (stateEnum.currentStatus() == status) {
                return stateEnum;
            }
        }
        throw new Exception("无该状态");
    }

    //下一节点
    public abstract StateEnum nextState();

    //拒绝节点
    public abstract StateEnum rejectState();

    //当前状态
    public abstract int currentStatus();

    //状态名称
    public abstract String statusName();
}

状态审核接口

实际业务中,只需要传递当前状态status和审核的动作statusType即可.

nextState对象得到审核后的状态信息,再根据实际业务走后续流程即可.

代码语言:javascript复制

static final int PASS = 1;

if (PASS == statusType) {
    // 审批通过
    nextState = StateEnum.get(status).nextState();
} else {
    // 审批拒绝
    nextState = StateEnum.get(status).rejectState();
}

   /**
     * 当前状态
     */
    private int status;

    /**
     * 审核动作 1通过 2拒绝
     */
    private int statusType;

封装通用装填审核接口

以上代码可以封装成一个接口,前端扭转状态时只需提供 1.业务ID 2.当前状态status 3.审核动作statusType

得到审核结果nextState后通过业务ID更新解耦业务,为了保证幂等性, 更新时需将前端传过来的当前状态也当做更新判断条件之一

代码语言:javascript复制

update table set status = nextState.currentStatus where 业务ID and status;

0 人点赞