赞
踩
关于这几个对比,文章比较多,这里就不赘述了。
这三个,我基本都有直接或间接使用过。
简单感受是:
squirrel-foundation,同事用过,功能丰富,较为轻量,上手简单。
Spring statemachine,自己调研过,和 Spring 天然集成,注解声明,功能丰富,同时上手较复杂,状态机实例不能单例使用,线程不安全。
stateless4j ,轻量、简单,轻度使用,很 nice,对代码侵入极小。GitHub - stateless4j/stateless4j: Lightweight Java State Machine
质量检测任务(简称:质检任务)的状态流转图:
new 一个类,名为:QcStateMachine 质检状态机。
依据上面的状态转移图,配置状态转移。
提前准备两个枚举类:状态枚举、时间枚举。前置态-接受到事件->后置态。
- private static final StateMachineConfig<QualityStatusEnum, QualityEventEnum> CONFIG = new StateMachineConfig<>();
-
- static {
- /*
- * 最初为 INIT 状态时
- */
- CONFIG.configure(QualityStatusEnum.INIT)
- // .permitDynamic(new TriggerWithParameters1<>(QualityEventEnum.APPLY_QUALITY_TASK, QcTask.class), qcTask -> {
- // return QualityStatusEnum.CHECKING;
- // })
- .permit(QualityEventEnum.APPLY_QUALITY_TASK, QualityStatusEnum.CHECKING)
- .permit(QualityEventEnum.SAVE_QUALITY_RESULT, QualityStatusEnum.CHECKING)
- .permit(QualityEventEnum.SUBMIT_QUALITY_RESULT, QualityStatusEnum.RECHECKING)
- .ignore(QualityEventEnum.DELETE);
-
- CONFIG.configure(QualityStatusEnum.CHECKING)
- .ignore(QualityEventEnum.SAVE_QUALITY_RESULT)
- .permit(QualityEventEnum.SUBMIT_QUALITY_RESULT, QualityStatusEnum.RECHECKING);
-
- CONFIG.configure(QualityStatusEnum.RECHECKING)
- .ignore(QualityEventEnum.SUBMIT_RECHECK_RESULT)
- .permit(QualityEventEnum.RECHECK_EXPIRE, QualityStatusEnum.RECHECKED);
-
- CONFIG.configure(QualityStatusEnum.RECHECKED)
- .permit(QualityEventEnum.AMEND, QualityStatusEnum.AMENDED)
- .permit(QualityEventEnum.AMEND_EXPIRE, QualityStatusEnum.AMENDED);
-
- }
- //构建状态机实例,传入当前状态和状态转移配置
- StateMachine<QualityStatusEnum, QualityEventEnum> sm = new StateMachine<>(current, CONFIG)
- //判断当前状态能不能接受目标事件: 提交质检结果
- if (sm.canFire(QualityEventEnum.SUBMIT_QUALITY_RESULT)) {
- // 中断
- }
-
- //接受事件,状态转移到下一个状态
- sm.fire();
-
- //更新表里的状态
- QualityStatusEnum nextState = sm.getState(); //推荐这样获取下一个状态,减少硬编码
- ...
上面时最简单的轻量使用。
如果需要在状态转移时,伴随一些动作逻辑,可以在状态转移配置中设置。
QcStateMachine 完整代码:
- import com.github.oxo42.stateless4j.StateMachine;
- import com.github.oxo42.stateless4j.StateMachineConfig;
- import com.sankuai.groceryrisk.common.core.exception.DialogException;
- import com.sankuai.groceryrisk.risk.investigation.service.constant.enums.QualityEventEnum;
- import com.sankuai.groceryrisk.risk.investigation.service.constant.enums.QualityStatusEnum;
- import lombok.extern.slf4j.Slf4j;
-
- /**
- * <p>
- *
- * @author L&J
- * @version 0.1
- * @since 2023/2/4 12:10
- */
- @Slf4j
- public class QcStateMachine {
-
- private static final StateMachineConfig<QualityStatusEnum, QualityEventEnum> CONFIG = new StateMachineConfig<>();
-
- static {
- /*
- * 最初为 INIT 状态时
- */
- CONFIG.configure(QualityStatusEnum.INIT)
- // .permitDynamic(new TriggerWithParameters1<>(QualityEventEnum.APPLY_QUALITY_TASK, QcTask.class), qcTask -> {
- // return QualityStatusEnum.CHECKING;
- // })
- .permit(QualityEventEnum.APPLY_QUALITY_TASK, QualityStatusEnum.CHECKING)
- .permit(QualityEventEnum.SAVE_QUALITY_RESULT, QualityStatusEnum.CHECKING)
- .permit(QualityEventEnum.SUBMIT_QUALITY_RESULT, QualityStatusEnum.RECHECKING)
- .ignore(QualityEventEnum.DELETE);
-
- CONFIG.configure(QualityStatusEnum.CHECKING)
- .ignore(QualityEventEnum.SAVE_QUALITY_RESULT)
- .permit(QualityEventEnum.SUBMIT_QUALITY_RESULT, QualityStatusEnum.RECHECKING);
-
- CONFIG.configure(QualityStatusEnum.RECHECKING)
- .ignore(QualityEventEnum.SUBMIT_RECHECK_RESULT)
- .permit(QualityEventEnum.RECHECK_EXPIRE, QualityStatusEnum.RECHECKED);
-
- CONFIG.configure(QualityStatusEnum.RECHECKED)
- .permit(QualityEventEnum.AMEND, QualityStatusEnum.AMENDED)
- .permit(QualityEventEnum.AMEND_EXPIRE, QualityStatusEnum.AMENDED);
-
- }
-
- public static StateMachine<QualityStatusEnum, QualityEventEnum> of(Integer sourceState) {
- return of(QualityStatusEnum.getByValue(sourceState));
- }
-
- public static StateMachine<QualityStatusEnum, QualityEventEnum> of(QualityStatusEnum sourceState) {
- return new StateMachine<>(sourceState, CONFIG);
- }
-
- public static boolean canFire(Integer current, QualityEventEnum event) {
- return canFire(QualityStatusEnum.getByValue(current), event);
- }
-
- /**
- * 当前状态是否接受当前事件
- * @param current 当前状态, 前置态
- * @param event 事件
- */
- public static boolean canFire(QualityStatusEnum current, QualityEventEnum event) {
- StateMachine<QualityStatusEnum, QualityEventEnum> sm = new StateMachine<>(current, CONFIG);
- return sm.canFire(event);
- }
-
- public static StateMachine<QualityStatusEnum, QualityEventEnum> checkFireOrThrow(Integer current, QualityEventEnum event) {
- return checkFireOrThrow(QualityStatusEnum.getByValue(current), event);
- }
-
- public static StateMachine<QualityStatusEnum, QualityEventEnum> checkFireOrThrow(QualityStatusEnum current, QualityEventEnum event) {
- StateMachine<QualityStatusEnum, QualityEventEnum> sm = new StateMachine<>(current, CONFIG);
- if (!sm.canFire(event)) {
- throw new DialogException("当前任务状态('{}')不可'{}'", current.getLabel(), event.getLabel());
- }
- return sm;
- }
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。