当前位置:   article > 正文

轻量级状态机框架 Sateless4j 实践_stateless4j permitdynamic

stateless4j permitdynamic

状态机选型

  • squirrel-foundation
  • Spring statemachine
  • stateless4j

关于这几个对比,文章比较多,这里就不赘述了。

这三个,我基本都有直接或间接使用过。

简单感受是:

squirrel-foundation,同事用过,功能丰富,较为轻量,上手简单。

Spring statemachine,自己调研过,和 Spring 天然集成,注解声明,功能丰富,同时上手较复杂,状态机实例不能单例使用,线程不安全。

stateless4j ,轻量、简单,轻度使用,很 nice,对代码侵入极小。GitHub - stateless4j/stateless4j: Lightweight Java State Machine

实践

质量检测任务(简称:质检任务)的状态流转图:

new 一个类,名为:QcStateMachine 质检状态机

依据上面的状态转移图,配置状态转移。

提前准备两个枚举类:状态枚举、时间枚举。前置态-接受到事件->后置态

  1. private static final StateMachineConfig<QualityStatusEnum, QualityEventEnum> CONFIG = new StateMachineConfig<>();
  2. static {
  3. /*
  4. * 最初为 INIT 状态时
  5. */
  6. CONFIG.configure(QualityStatusEnum.INIT)
  7. // .permitDynamic(new TriggerWithParameters1<>(QualityEventEnum.APPLY_QUALITY_TASK, QcTask.class), qcTask -> {
  8. // return QualityStatusEnum.CHECKING;
  9. // })
  10. .permit(QualityEventEnum.APPLY_QUALITY_TASK, QualityStatusEnum.CHECKING)
  11. .permit(QualityEventEnum.SAVE_QUALITY_RESULT, QualityStatusEnum.CHECKING)
  12. .permit(QualityEventEnum.SUBMIT_QUALITY_RESULT, QualityStatusEnum.RECHECKING)
  13. .ignore(QualityEventEnum.DELETE);
  14. CONFIG.configure(QualityStatusEnum.CHECKING)
  15. .ignore(QualityEventEnum.SAVE_QUALITY_RESULT)
  16. .permit(QualityEventEnum.SUBMIT_QUALITY_RESULT, QualityStatusEnum.RECHECKING);
  17. CONFIG.configure(QualityStatusEnum.RECHECKING)
  18. .ignore(QualityEventEnum.SUBMIT_RECHECK_RESULT)
  19. .permit(QualityEventEnum.RECHECK_EXPIRE, QualityStatusEnum.RECHECKED);
  20. CONFIG.configure(QualityStatusEnum.RECHECKED)
  21. .permit(QualityEventEnum.AMEND, QualityStatusEnum.AMENDED)
  22. .permit(QualityEventEnum.AMEND_EXPIRE, QualityStatusEnum.AMENDED);
  23. }

  1. //构建状态机实例,传入当前状态和状态转移配置
  2. StateMachine<QualityStatusEnum, QualityEventEnum> sm = new StateMachine<>(current, CONFIG)
  3. //判断当前状态能不能接受目标事件: 提交质检结果
  4. if (sm.canFire(QualityEventEnum.SUBMIT_QUALITY_RESULT)) {
  5. // 中断
  6. }
  7. //接受事件,状态转移到下一个状态
  8. sm.fire();
  9. //更新表里的状态
  10. QualityStatusEnum nextState = sm.getState(); //推荐这样获取下一个状态,减少硬编码
  11. ...


上面时最简单的轻量使用。

如果需要在状态转移时,伴随一些动作逻辑,可以在状态转移配置中设置。

QcStateMachine 完整代码:

  1. import com.github.oxo42.stateless4j.StateMachine;
  2. import com.github.oxo42.stateless4j.StateMachineConfig;
  3. import com.sankuai.groceryrisk.common.core.exception.DialogException;
  4. import com.sankuai.groceryrisk.risk.investigation.service.constant.enums.QualityEventEnum;
  5. import com.sankuai.groceryrisk.risk.investigation.service.constant.enums.QualityStatusEnum;
  6. import lombok.extern.slf4j.Slf4j;
  7. /**
  8. * <p>
  9. *
  10. * @author L&J
  11. * @version 0.1
  12. * @since 2023/2/4 12:10
  13. */
  14. @Slf4j
  15. public class QcStateMachine {
  16. private static final StateMachineConfig<QualityStatusEnum, QualityEventEnum> CONFIG = new StateMachineConfig<>();
  17. static {
  18. /*
  19. * 最初为 INIT 状态时
  20. */
  21. CONFIG.configure(QualityStatusEnum.INIT)
  22. // .permitDynamic(new TriggerWithParameters1<>(QualityEventEnum.APPLY_QUALITY_TASK, QcTask.class), qcTask -> {
  23. // return QualityStatusEnum.CHECKING;
  24. // })
  25. .permit(QualityEventEnum.APPLY_QUALITY_TASK, QualityStatusEnum.CHECKING)
  26. .permit(QualityEventEnum.SAVE_QUALITY_RESULT, QualityStatusEnum.CHECKING)
  27. .permit(QualityEventEnum.SUBMIT_QUALITY_RESULT, QualityStatusEnum.RECHECKING)
  28. .ignore(QualityEventEnum.DELETE);
  29. CONFIG.configure(QualityStatusEnum.CHECKING)
  30. .ignore(QualityEventEnum.SAVE_QUALITY_RESULT)
  31. .permit(QualityEventEnum.SUBMIT_QUALITY_RESULT, QualityStatusEnum.RECHECKING);
  32. CONFIG.configure(QualityStatusEnum.RECHECKING)
  33. .ignore(QualityEventEnum.SUBMIT_RECHECK_RESULT)
  34. .permit(QualityEventEnum.RECHECK_EXPIRE, QualityStatusEnum.RECHECKED);
  35. CONFIG.configure(QualityStatusEnum.RECHECKED)
  36. .permit(QualityEventEnum.AMEND, QualityStatusEnum.AMENDED)
  37. .permit(QualityEventEnum.AMEND_EXPIRE, QualityStatusEnum.AMENDED);
  38. }
  39. public static StateMachine<QualityStatusEnum, QualityEventEnum> of(Integer sourceState) {
  40. return of(QualityStatusEnum.getByValue(sourceState));
  41. }
  42. public static StateMachine<QualityStatusEnum, QualityEventEnum> of(QualityStatusEnum sourceState) {
  43. return new StateMachine<>(sourceState, CONFIG);
  44. }
  45. public static boolean canFire(Integer current, QualityEventEnum event) {
  46. return canFire(QualityStatusEnum.getByValue(current), event);
  47. }
  48. /**
  49. * 当前状态是否接受当前事件
  50. * @param current 当前状态, 前置态
  51. * @param event 事件
  52. */
  53. public static boolean canFire(QualityStatusEnum current, QualityEventEnum event) {
  54. StateMachine<QualityStatusEnum, QualityEventEnum> sm = new StateMachine<>(current, CONFIG);
  55. return sm.canFire(event);
  56. }
  57. public static StateMachine<QualityStatusEnum, QualityEventEnum> checkFireOrThrow(Integer current, QualityEventEnum event) {
  58. return checkFireOrThrow(QualityStatusEnum.getByValue(current), event);
  59. }
  60. public static StateMachine<QualityStatusEnum, QualityEventEnum> checkFireOrThrow(QualityStatusEnum current, QualityEventEnum event) {
  61. StateMachine<QualityStatusEnum, QualityEventEnum> sm = new StateMachine<>(current, CONFIG);
  62. if (!sm.canFire(event)) {
  63. throw new DialogException("当前任务状态('{}')不可'{}'", current.getLabel(), event.getLabel());
  64. }
  65. return sm;
  66. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/811382
推荐阅读
相关标签
  

闽ICP备14008679号