阿里状态机引擎实现

状态机的技术选型看这篇就够了,最后一个直叫好! - 掘金

实现一个状态机引擎,教你看清DSL的本质_cola状态机-CSDN博客

一、引入jar包

<!--阿里状态机jar-->
<dependency><groupId>com.alibaba.cola</groupId><artifactId>cola-component-statemachine</artifactId><version>4.3.2</version>
</dependency>        

二、引入流转类型枚举

package com.lx.designPattern.statepattern.statemachine.enums;/*** 流转类型枚举* @author lwp* @date 2023-07-06 14:56:27* @version 1.0*/
public enum TransitionTypeEnum {/*** 内部流转*/INTERNAL,/*** 外部流转*/EXTERNAL,/*** 多状态外部流转*/EXTERNALS;
}

三、引入事件枚举

package com.lx.designPattern.statepattern.statemachine.enums;/*** 履约状态事件枚举** @author lwp* @version 1.0* @date 2023-07-06 13:40:11*/
public enum FulfillmentStatusEventEnum {/*** 开始租赁非标商品履约*/BEGIN_RENT_NON_STANDARD_GOODS_FULFILLMENT,/*** 完成资源匹配*/MATCH_RESOURCE,/*** 完成租赁交付*/COMPLETE_RENT_DELIVER,/*** 重置履约计划*/RESET_FULFILLMENT,/*** 取消履约单*/CANCEL_FULFILLMENT,/*** 创建售车交付履约单*/CREATE_SALE_DELIVER_FULFILLMENT,/*** 完成服务执行中*/COMPLETE_SERVICE_FULFILLMENT,/*** 非灰度履约单交付*/NON_GRAY_DELIVER,/*** 欢乐租备车*/HAPPY_RENT_PLAN_CAR,/*** 开始替换车履约*/START_REPLACE_DELIVER_FULFILLMENT,/*** 开始常规租赁退车履约*/START_RENT_BACK_CAR_FULFILLMENT,/*** 完成替换车车退车*/COMPLETE_REPLACE_BACK_CAR_FULFILLMENT,/*** 完成租赁退车*/COMPLETE_RENT_BACK_CAR_FULFILLMENT,/*** 取消履约 (新的)*/CANCEL_FULFILLMENT_2ND,/*** 完成服务履约*/COMPLETE_VEHICLE_SERVICE,/*** 渠道商履约*/CHANNEL_FULFILLMENT,;
}

四、引入流转状态枚举

package com.lx.designPattern.statepattern.statemachine.enums;import com.lx.exception.BusinessException;import java.util.Objects;/*** 履约单状态枚举* @author lwp* @date 2023/1/5 9:16* @version 1.0*/
public enum FulfillmentStatusEnum {/*** 初始状态*/INITIAL(0, "初始状态"),/*** 待匹配*/WAIT_MATCH(2, "待匹配"),/*** 进行中*/IN_PROGRESS(3, "进行中"),/*** 已完成*/COMPLETED(4, "已完成"),/*** 已取消*/CANCELED(5, "已取消"),;private Integer status;private String desc;FulfillmentStatusEnum(Integer status, String desc) {this.status = status;this.desc = desc;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}public static FulfillmentStatusEnum getByStatus(Integer status) {for (FulfillmentStatusEnum fulfillmentStatusEnum : FulfillmentStatusEnum.values()) {if (Objects.equals(status, fulfillmentStatusEnum.getStatus())) {return fulfillmentStatusEnum;}}throw new BusinessException("未找到履约状态枚举");}
}
 1.需要处理的业务参数类
package com.lx.designPattern.statepattern.statemachine.dto;import lombok.Data;/*** 履约单dto* @author lwp* @date 2023-07-25 16:22:04* @version 1.0*/
@Data
public class FulfillmentBillDTO {/*** 交易订单*/private A a;/*** 履约主单*/private B b;/*** 车辆履约子单*/private C c;
}

五、准备状态机

package com.lx.designPattern.statepattern.statemachine;import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory;
import com.lx.designPattern.statepattern.statemachine.statustransition.FulfillmentStatusTransition;
import com.lx.designPattern.statepattern.statemachine.dto.FulfillmentBillDTO;
import com.lx.designPattern.statepattern.statemachine.enums.FulfillmentStatusEnum;
import com.lx.designPattern.statepattern.statemachine.enums.FulfillmentStatusEventEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.List;/*** 履约状态机** @author lwp* @version 1.0* @date 2023-07-27 10:31:27*/
@Slf4j
@Lazy
@Component
public class FulfillmentStatusStateMachine {/*** 状态机ID*/private static final String MACHINE_ID = "FulfillmentStatusStateMachine";/*** 状态机*/private StateMachine<FulfillmentStatusEnum, FulfillmentStatusEventEnum, FulfillmentBillDTO> stateMachine;@Autowiredprivate List<FulfillmentStatusTransition> fulfillmentStatusTransitions;/* ******************************* 履约单状态流转 *****************************//*** 初始化*/@PostConstructpublic void init() {// 创建状态机StateMachineBuilder<FulfillmentStatusEnum, FulfillmentStatusEventEnum, FulfillmentBillDTO> stateMachineBuilder= StateMachineBuilderFactory.create();// 添加没有命中配置规则时的回调stateMachineBuilder.setFailCallback(this::stateMachineFailCallback);// 初始化transitioninitTransition(stateMachineBuilder);stateMachine = stateMachineBuilder.build(MACHINE_ID);}/*** 触发流转*/public FulfillmentStatusEnum fireEvent(FulfillmentStatusEnum status,FulfillmentStatusEventEnum event,FulfillmentBillDTO fulfillmentBill) {FulfillmentStatusEnum resultStatus = stateMachine.fireEvent(status, event, fulfillmentBill);// 如果结果状态和源状态相同,代表流转失败if (resultStatus == status) {log.warn("履约单{}状态流转失败, from:{}, to:{}, event:{}",fulfillmentBill.getMainFulfillmentBill().getFulfillmentCode(),status.getStatus(),resultStatus.getDesc(),event);} else {log.info("履约单{}状态流转, from:{}, to:{}, event:{}",fulfillmentBill.getMainFulfillmentBill().getFulfillmentCode(),status.getStatus(),resultStatus.getDesc(),event);}return resultStatus;}/*** 没有命中配置规则时的回调*/private void stateMachineFailCallback(FulfillmentStatusEnum status,FulfillmentStatusEventEnum event,FulfillmentBillDTO fulfillmentBill) {log.error("履约单{}状态流转失败: 未找到匹配的流转规则, from:{}, event:{}",fulfillmentBill.getMainFulfillmentBill().getId(),status.getDesc(),event);}/*** 初始化transition*/private void initTransition(StateMachineBuilder<FulfillmentStatusEnum, FulfillmentStatusEventEnum,FulfillmentBillDTO> builder) {fulfillmentStatusTransitions.forEach(transition -> {switch (transition.getTransitionType()) {case INTERNAL:if (transition.getWithin().isPresent()) {builder.internalTransition().within(transition.getWithin().get()).on(transition.getEvent()).when(transition.getCondition()).perform(transition.getAction());} else {log.error("初始化履约单内部状态流转错误: 缺少within参数");throw new IllegalArgumentException("履约状态状态机初始化失败");}break;case EXTERNAL:if (transition.getFrom().isPresent() && transition.getTo().isPresent()) {builder.externalTransition().from(transition.getFrom().get()).to(transition.getTo().get()).on(transition.getEvent()).when(transition.getCondition()).perform(transition.getAction());} else {log.error("初始化履约单外部状态流转错误: 缺少from或to参数");throw new IllegalArgumentException("履约状态状态机初始化失败");}break;case EXTERNALS:if (transition.getFromAmong().isPresent() && transition.getTo().isPresent()) {builder.externalTransitions().fromAmong(transition.getFromAmong().get()).to(transition.getTo().get()).on(transition.getEvent()).when(transition.getCondition()).perform(transition.getAction());} else {log.error("初始化履约单多状态外部状态流转错误: 缺少fromAmong或to参数");throw new IllegalArgumentException("履约状态状态机初始化失败");}break;default:log.error("不支持的流转类型:{}", transition.getTransitionType());}});}
}

六、准备流转接口

package com.lx.designPattern.statepattern.statemachine.statustransition;import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.Condition;
import com.lx.designPattern.statepattern.statemachine.dto.FulfillmentBillDTO;
import com.lx.designPattern.statepattern.statemachine.enums.FulfillmentStatusEnum;
import com.lx.designPattern.statepattern.statemachine.enums.FulfillmentStatusEventEnum;
import com.lx.designPattern.statepattern.statemachine.enums.TransitionTypeEnum;import java.util.Optional;/*** 履约单状态流转* @author lwp* @date 2023-07-06 15:08:18* @version 1.0*/
public interface FulfillmentStatusTransition {/*** 获取类转类型* @return 流转类型*/TransitionTypeEnum getTransitionType();/*** 获取within参数(内部流转必需)* @return within*/default Optional<FulfillmentStatusEnum> getWithin() {return Optional.empty();}/*** 获取from参数(外部流转必需)* @return from*/default Optional<FulfillmentStatusEnum> getFrom() {return Optional.empty();}/*** 获取fromAmong参数(多状态外部流转必需)* @return fromAmong*/default Optional<FulfillmentStatusEnum[]> getFromAmong() {return Optional.empty();}/*** 获取to参数(外部流转和多状态外部流转必需)* @return to*/default Optional<FulfillmentStatusEnum> getTo() {return Optional.empty();};/*** 获取event* @return on参数*/FulfillmentStatusEventEnum getEvent();/*** 获取condition* @return when*/Condition<FulfillmentBillDTO> getCondition();/*** 获取action* @return preform*/Action<FulfillmentStatusEnum, FulfillmentStatusEventEnum, FulfillmentBillDTO> getAction();
}

七、实现流转接口和定义流转规则

package com.lx.designPattern.statepattern.statemachine.statustransition;import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.Condition;
import com.lx.designPattern.statepattern.statemachine.dto.FulfillmentBillDTO;
import com.lx.designPattern.statepattern.statemachine.dto.MainFulfillmentBill;
import com.lx.designPattern.statepattern.statemachine.enums.FulfillmentStatusEnum;
import com.lx.designPattern.statepattern.statemachine.enums.FulfillmentStatusEventEnum;
import com.lx.designPattern.statepattern.statemachine.enums.TransitionTypeEnum;
import org.springframework.stereotype.Component;import java.util.Optional;/*** 完成履约状态流转* @author lwp* @date 2023-07-12 10:30:32* @version 1.0*/
@Component
public class CompleteFulfillmentTransition implements FulfillmentStatusTransition {//@Autowired//private FulfillmentBillDaoService fulfillmentBillDaoService;@Overridepublic TransitionTypeEnum getTransitionType() {return TransitionTypeEnum.EXTERNAL;}@Overridepublic Optional<FulfillmentStatusEnum> getFrom() {return Optional.of(FulfillmentStatusEnum.IN_PROGRESS);}@Overridepublic Optional<FulfillmentStatusEnum> getTo() {return Optional.of(FulfillmentStatusEnum.COMPLETED);}@Overridepublic FulfillmentStatusEventEnum getEvent() {return FulfillmentStatusEventEnum.COMPLETE_RENT_DELIVER;}@Overridepublic Condition<FulfillmentBillDTO> getCondition() {return (fulfillmentBillDTO -> true);}@Overridepublic Action<FulfillmentStatusEnum, FulfillmentStatusEventEnum, FulfillmentBillDTO> getAction() {return (srcState, tarState, event, fulfillmentBillDTO) -> {// 修改履约单状态MainFulfillmentBill updateMainBill = new MainFulfillmentBill();updateMainBill.setId(fulfillmentBillDTO.getMainFulfillmentBill().getId());updateMainBill.setStatus(tarState.getStatus());//fulfillmentBillDaoService.updateMainBillById(updateMainBill);System.out.println("状态改为完成了");};}
}

八、准备测试类测试

package com.lx.designPattern;import com.lx.designPattern.statepattern.statemachine.FulfillmentStatusStateMachine;
import com.lx.designPattern.statepattern.statemachine.business.InsuranceStatusChangeServiceImpl;
import com.lx.designPattern.statepattern.statemachine.dto.FulfillmentBillDTO;
import com.lx.designPattern.statepattern.statemachine.dto.MainFulfillmentBill;
import com.lx.designPattern.statepattern.statemachine.enums.FulfillmentStatusEnum;
import com.lx.designPattern.statepattern.statemachine.enums.FulfillmentStatusEventEnum;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;/*** @Desc 阿里状态机测试类* @author lwp* @version 1.0* @date 2024-01-13 22:16:22*/
@RunWith(SpringRunner.class)
@SpringBootTest(properties = "dev")
public class StateMachineTest {@Autowiredprivate FulfillmentStatusStateMachine fulfillmentStatusStateMachine;@Testpublic void handStatusChangeComplete() {FulfillmentBillDTO billDTO = new FulfillmentBillDTO();MainFulfillmentBill mainFulfillmentBill = new MainFulfillmentBill();mainFulfillmentBill.setFulfillmentCode("LY001");mainFulfillmentBill.setStatus(1);billDTO.setMainFulfillmentBill(mainFulfillmentBill);fulfillmentStatusStateMachine.fireEvent(FulfillmentStatusEnum.getByStatus(3),FulfillmentStatusEventEnum.COMPLETE_RENT_DELIVER,billDTO);}}

 九、测试效果如下图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/620634.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大创项目推荐 深度学习疲劳检测 驾驶行为检测 - python opencv cnn

文章目录 0 前言1 课题背景2 相关技术2.1 Dlib人脸识别库2.2 疲劳检测算法2.3 YOLOV5算法 3 效果展示3.1 眨眼3.2 打哈欠3.3 使用手机检测3.4 抽烟检测3.5 喝水检测 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习加…

虚拟机配置固定IP

1.DHCP 当前我们虚拟机的Linux操作系统&#xff0c;其IP地址是通过DHCP服务获取的。 DHCP&#xff1a;动态获取IP地址&#xff0c;即每次重启设备后都会获取一次&#xff0c;可能导致IP地址频繁变更&#xff0c;这就会给我们带来不方便&#xff0c;因为如果我们每次重启设备都…

2024年AMC8模拟考试实测流程、注意事项和常见问题

和往年的AMC8比赛一样&#xff0c;在正式比赛的前一周左右会开放两天的模拟考试时间&#xff0c;AMC8的主办方建议所有的参赛选手重视且参加模拟考试&#xff0c;以测试设备、熟悉流程&#xff0c;避免将来正式考试不小心违规&#xff0c;或者设备不给力。 2024年的AMC8模拟考…

线性代数——(期末突击)概率统计习题(概率的性质、全概率公式)

目录 概率的性质 题一 全概率公式 题二 题三 概率的性质 有限可加性&#xff1a; 若有限个事件互不相容&#xff0c;则 单调性&#xff1a; 互补性&#xff1a; 加法公式&#xff1a; 可分性&#xff1a; 题一 在某城市中共发行三种报纸&#xff1a;甲、乙、丙。在这个…

Flutter之运行错误:Error: Member notfound: ‘SystemChrome .setEnabledSystemuIOverlays‘

项目由于引入的包导致报错&#xff1a; Error: Member notfound: SystemChrome .setEnabledSystemuIOverlays 主要原因是因为包里的方法有变动。 解决办法&#xff1a; 将AppDate\Local\Pub\Cache\hosted\pub.dev\r_scan-0.1.61\lib\src\r_scan_view.dart文件中的 原方法&am…

设计模式——1_4 外观(Facade)

文章目录 定义图纸一个例子&#xff1a;自动生成一杯茶沏茶的流程组合方式一&#xff1a;直接组合方法二&#xff1a;外观 碎碎念多个外观对象外观和封装外观和单例姑妄言之 定义 为子系统中的一组接口提供一个一致的界面&#xff0c;外观模式定义了一个高层接口&#xff0c;这…

【120版本】最新谷歌浏览器驱动下载地址

在使用selenium时可能会遇到谷歌浏览器和谷歌驱动器版本不一致的问题&#xff0c;并且国内可以搜到的谷歌浏览器下载地址里面最新的驱动器只有114版本的&#xff0c;但目前谷歌浏览器最新版本是120。所以这里记录下最新版本120谷歌驱动器下载地址&#xff1a; Chrome for Test…

Dobbo---分布式系统通信方式

通信方式 分布式系统通信方式1. RMIRMI 通信实现案例2. RPC常用RPC框架 分布式系统通信方式 1. RMI RMI ( Remote Method Invocation 远程方法调用) 图1.1 客户端-服务端通信方式 客户端将要调用的方法及参数&#xff0c;打包为辅助对象&#xff0c;通过网络socket&#xff…

【自控实验】3. 带有饱和非线性环节控制系统相平面分析

本科课程实验报告&#xff0c;有太多公式和图片了&#xff0c;干脆直接转成图片了 仅分享和记录&#xff0c;不保证全对 实验内容&#xff1a; 有无非线性环节的相轨迹对比&#xff0c;并求超调量。 在输入单位阶跃信号Xsr时&#xff0c;用示波器观察和记录系统输入饱和非线…

Hadoop-HA高可用

一、集群规划 二、HDFS高可用 官方地址 在opt目录下创建一个ha文件夹&#xff0c;将/opt/module/下的 hadoop-3.1.3拷贝到/opt/ha目录下&#xff08;记得删除data 和 log目录&#xff09; 配置core-site.xml hdfs-site.xml <configuration><!-- NameNode数据存…

个人网站制作 Part 4 添加响应式设计 | Web开发项目

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 添加响应式设计&#x1f528;移动优先的响应式样式&#x1f527;步骤 1: 添加媒体查询 &#x1f528;图片和布局调整&#x1f527;步骤 2: 使用响应式图片&#x1f527;步…

如何使用网络测试仪构造特殊流量

为什么要仿真特殊流量 在现网中&#xff0c;网络流量时常伴随着突发&#xff0c;突发流量可能会造成网络的拥塞&#xff0c;从而产生丢包、抖动和时延&#xff0c;导致网络服务质量整体下降。面对宏观上的突发&#xff0c;通常采用在网络设备入向限速或者流量整形功能来消除突…

使用代理IP池实现多线程爬虫的方法

目录 前言 代理IP的概念和作用 为什么使用代理IP池 代理IP池的实现步骤 代码实现 注意事项 总结 前言 随着互联网的发展&#xff0c;爬虫技术在各个领域中被广泛应用。然而&#xff0c;目标网站对爬虫的限制也日益严格&#xff0c;例如限制单个IP的请求频率。为了解决这…

从0到1:如何建立一个大规模多语言代码生成预训练模型

国产AI辅助编程工具 CodeGeeX 是一个使用AI大模型为基座的辅助编程工具&#xff0c;帮助开发人员更快的编写代码。可以自动完成整个函数的编写&#xff0c;只需要根据注释或Tab按键即可。它已经在Java、JavaScript和Python等二十多种语言上进行了训练&#xff0c;并基于大量公开…

三轴加速度计LIS2DW12开发(3)----检测活动和静止状态

e2studio开发三轴加速度计LIS2DW12.3--检测活动和静止状态 概述视频教学样品申请源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback ()…

mongoose6.0版以上操作mongodb数据库的基本使用

1、介绍 Mongoose 是一个对象文档模型库&#xff0c;官网 http://www.mongoosejs.net/ 2、作用 方便使用代码操作 mongodb 数据库 3、使用流程 3.1、链接数据库 //1. 安装 mongoose---> npm install mongoose --save//2. 导入 mongoose const mongoose require(&quo…

航模遥控开关电路图大全

航模遥控开关电路图&#xff08;一&#xff09;&#xff1a;单通道航模遥控器的构造 遥控装置一般应用于车模、航模等领域&#xff0c;用以实现对靶机、航模、玩具等的自动控制。下面介绍一种无线比例电机遥控器的制作方法。它选用易购元件&#xff0c;具有原理简单、性能可靠…

28 星际旋转

效果演示 实现了一个太阳系动画&#xff0c;其中包括了地球、火星、金星、土星、水星、天王星、海王星以及火卫二号等行星的动画效果。太阳系的行星都被放在一个固定的容器中&#xff0c;并使用CSS动画来实现旋转和移动的效果。当太阳系的行星绕着太阳运行时&#xff0c;它们会…

电子学会C/C++编程等级考试2021年09月(四级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:最佳路径 如下所示的由正整数数字构成的三角形: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。你的任务就是求出最佳路径…

Rust-trait

Rust语言中的trait是非常重要的概念。 在Rust中&#xff0c;trait这一个概念承担了多种职责。在中文里&#xff0c;trait可以翻译为“特征”“特点”“特性”等。 成员方法 trait中可以定义函数。用例子来说明&#xff0c;我们定义如下的trait: 上面这个trait包含了一个方法…