首页>资讯 > 聚焦资讯 > 正文

聊聊Cola-StateMachine轻量级状态机的实现 天天即时看

来源:博客园    2023-06-07 12:32:32

背景

在分析Seata的saga模式实现时,实在是被其复杂的 json 状态语言定义文件劝退,我是有点没想明白为啥要用这么来实现状态机;盲猜可能是基于可视化的状态机设计器来定制化流程,更方便快捷且上手快吧,毕竟可以通过UI直接操作,设计状态流转图,但我暂时不太能get到。对于Saga模式的实现,之前的博文中已经阐述了基于状态机模式实现Saga,是比较常见且合适的做法,因此了解了下Java中的状态机实现方案,以后有相关的业务场景也可以直接上手使用状态机。

Cola-StateMachine

Cola-StateMachine组件是一种轻量级的、无状态的、基于注解的状态机实现,可以方便地管理订单等业务对象的状态转换。COLA框架的状态机使用了连贯接口(Fluent Interfaces)来定义状态和事件,以及对应的动作和检查。COLA框架的状态机是COLA 4.0应用架构的一部分,旨在控制复杂度,提高开发效率。开发背景可见实现一个状态机引擎,教你看清DSL的本质。

基础模型

在Cola-StateMachine组件中有如下的抽象概念模型:


(资料图片)

1.State:状态2.Event:事件,状态由事件触发,引起变化3.Transition:流转,表示从一个状态到另一个状态4.External Transition:外部流转,两个不同状态之间的流转5.Internal Transition:内部流转,同一个状态之间的流转6.Condition:条件,表示是否允许到达某个状态7.Action:动作,到达某个状态之后,可以做什么8.StateMachine:状态机

Cola-StateMachine链路图业务应用示例

基于订单业务的场景,做一个简单的demo。

关闭订单的简单流程图

关闭订单简单的状态流转图

添加依赖

    com.alibaba.cola    cola-component-statemachine    4.3.1

定义一个订单的实体类、订单状态的枚举值、订单事件的枚举值

@Data@Builderpublic class Order {    public OrderStatusEnum orderStatusEnum;    public Integer orderId;    public String orderName;}public enum OrderStatusEnum {    INIT("0", "待付款"),    WAITING_FOR_DELIVERY("1", "待发货"),    HAVE_BEEN_DELIVERY("2", "已发货"),    CLOSE("3", "已取消");    private final String code;    private final String info;    OrderStatusEnum(String code, String info)    {        this.code = code;        this.info = info;    }    public String getCode()    {        return code;    }    public String getInfo()    {        return info;    }}public enum OrderEvent {    /**     * 用户关闭     */    USER_CLOSE("0", "用户取消"),    /**     * 管理员关闭     */    ADMIN_CLOSE("1", "后台取消"),    /**     * 超时关闭     */    OVERTIME_CLOSE("2", "超时取消"),    /**     * 检查错误关闭     */    CHECK_ERROR_CLOSE("3", "上级审核取消"),    /**     * 用户付费     */    USER_PAY("4", "用户支付");    /**     * 密码     */    private final String code;    /**     * 信息     */    private final String info;    /**     * 订单事件     *     * @param code 密码     * @param info 信息     */    OrderEvent(String code, String info) {        this.code = code;        this.info = info;    }    /**     * 获取代码     *     * @return {@link String}     */    public String getCode() {        return code;    }    /**     * 获取信息     *     * @return {@link String}     */    public String getInfo() {        return info;    }}

在容器启动的时候注册一个订单状态变更的工厂

@Componentpublic class StateMachineBuilderConfig {    @Autowired    UserCloseAction userCloseAction;    @Bean("orderOperaMachine")    public StateMachine orderOperaMachine() {        String ORDER_OPERA = "order_opera";        StateMachineBuilder builder = StateMachineBuilderFactory.create();        //订单从初始化状态-待发货-状态-转到-关闭订单状态--用户关闭        builder.externalTransitions()                .fromAmong(OrderStatusEnum.INIT, OrderStatusEnum.WAITING_FOR_DELIVERY)                .to(OrderStatusEnum.CLOSE)                .on(OrderEvent.USER_CLOSE)                .when(checkCondition())                .perform(userCloseAction);        //订单从-初始化状态-已发货-待发货--转到-关闭订单状态--后台操作人员关闭        builder.externalTransitions()                .fromAmong(OrderStatusEnum.INIT, OrderStatusEnum.HAVE_BEEN_DELIVERY, OrderStatusEnum.WAITING_FOR_DELIVERY)                .to(OrderStatusEnum.CLOSE)                .on(OrderEvent.ADMIN_CLOSE)                .when(checkCondition())                .perform(doAction());        //订单从等待发货状态-转为-订单关闭状态-超时关闭        builder.externalTransition()                .from(OrderStatusEnum.WAITING_FOR_DELIVERY)                .to(OrderStatusEnum.CLOSE)                .on(OrderEvent.OVERTIME_CLOSE)                .when(checkCondition())                .perform(doAction());        //订单从待发货状态--转为-订单关闭状态-上级审批不通过关闭        builder.externalTransition()                .from(OrderStatusEnum.WAITING_FOR_DELIVERY)                .to(OrderStatusEnum.CLOSE)                .on(OrderEvent.CHECK_ERROR_CLOSE)                .when(checkCondition())                .perform(doAction());        //订单从初始化状态--转为待发货状态--用户支付完毕动        builder.externalTransition()                .from(OrderStatusEnum.INIT)                .to(OrderStatusEnum.WAITING_FOR_DELIVERY)                .on(OrderEvent.USER_PAY)                .when(checkCondition())                .perform(doAction());        StateMachine orderOperaMachine = builder.build(ORDER_OPERA);        //打印uml图        String plantUML = orderOperaMachine.generatePlantUML();        System.out.println(plantUML);        return orderOperaMachine;    }    private Condition checkCondition() {        return (ctx) -> {            return true;        };    }    private Action doAction() {        return (from, to, event, ctx) -> {            System.out.println(ctx.getOrderName() + " 正在操作 " + ctx.getOrderId() + " from:" + from + " to:" + to + " on:" + event);        };    }}

在定义一个特殊的,只是举个例子,可以通过集成的方式集成实现一个用户关单的具体操作

@Componentpublic class UserCloseAction implements Action {    @Override    public void execute(OrderStatusEnum from, OrderStatusEnum to, OrderEvent event, Order context) {        System.out.println("用户关闭流程开始走了");        System.out.println("从这个状态-【" + from.getInfo() + "】-转为+【" + to.getInfo() + "】 的状态");        System.out.println("上下文信息:" + context.toString());        System.out.println("中间执行的一些操作.......");        System.out.println("用户关闭流程完毕了");    }}

定义一个 controller 的操作接口

@RestControllerpublic class OrderOperaController {    @Autowired    @Qualifier("orderOperaMachine")    StateMachine orderOperaMachine;    /**     * 场景1-用户关闭订单     *     * @return {@link Boolean}     */    @RequestMapping("userclose")    public Boolean userCloseOrder() {        //把订单状态改为关闭        String machineId = orderOperaMachine.getMachineId();        System.out.println(machineId);        Order order = Order.builder().orderId(1).orderName("用户").orderStatusEnum(OrderStatusEnum.INIT).build();        OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.INIT,OrderEvent.USER_CLOSE, order);        System.out.println(orderStatusEnum.toString());        return true;    }    /**     * 场景2-管理员关闭订单     *     * @return {@link Boolean}     */    @RequestMapping("adminClose")    public Boolean adminCloseOrder() {        //把订单状态改为关闭        Order order = Order.builder().orderId(1).orderName("后台操作人员").orderStatusEnum(OrderStatusEnum.HAVE_BEEN_DELIVERY).build();        OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.HAVE_BEEN_DELIVERY, OrderEvent.ADMIN_CLOSE, order);        System.out.println(orderStatusEnum.toString());        return true;    }    /**     * 场景3-超时关闭订单     *     * @return {@link Boolean}     */    @RequestMapping("overTimeclose")    public Boolean overTimeCloseOrder() {        //把订单状态改为关闭        Order order = Order.builder().orderId(1).orderName("超时了关闭订单")                .orderStatusEnum(OrderStatusEnum.WAITING_FOR_DELIVERY).build();        //OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.CLOSE, OrderEvent.OVERTIME_CLOSE, order);        OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.WAITING_FOR_DELIVERY, OrderEvent.OVERTIME_CLOSE, order);        System.out.println(orderStatusEnum.toString());        return true;    }    /**     * 场景4-检查错误关闭订单     *     * @return {@link Boolean}     */    @RequestMapping("checkErrorClose")    public Boolean checkErrorCloseOrder() {        //把订单状态改为关闭        Order order = Order.builder().orderId(1).orderName("上级检查错误").orderStatusEnum(OrderStatusEnum.WAITING_FOR_DELIVERY).build();        OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.WAITING_FOR_DELIVERY, OrderEvent.CHECK_ERROR_CLOSE, order);        System.out.println(orderStatusEnum.toString());        return true;    }}

启动程序

安装UML

随便新建一个uml文件,然后将启动程序的控制台输出内容复制到uml中

最后运行下

关键词:

聊聊Cola-StateMachine轻量级状态机的实现 天天即时看

Cola-StateMachine组件是一种轻量级的、无状态的、基于注解的状态机实

边框条配置及使用

边框条配置及使用-作者:卢粤人适用版本:NX10及以上 边框条的功能协

济宁临时身份证在哪里办理?|天天快报

一、办理地点(一)网上办理通过“济宁微警务”进行网上办理,进入后选择

2023年济南槐荫区户籍适龄儿童入学信息登记公告

一、入学信息登记对象和条件1 年满六周岁(2017年8月31日前出生)的适龄

2023济南高考日期是几号

考试科目及时间安排成绩数据汇总由省教育招生考试院统一组织。国家统一

讯息:济南槐荫区外来随迁子女幼升小小学报名要求及条件2023

入学信息登记对象和条件年满6周岁(2017年8月31日前出生),具备学习和自

环球报道:2023厦门翔安区秋季幼升小入学办法(港澳台等适龄儿童)

翔安区2023年秋季小学招生工作意见的通知港澳台华侨和外籍适龄儿童入学

全球即时看!连江县城区小学招生划片范围

2023年连江县中小学入学政策尚未发布,以下为2022年划片范围参考:2022

2023南召县高考考点有哪些?

2023南召县高考考点有哪些?第一高级中学考点、现代中学考点、衡越实验

每日看点!2023南阳中考满分多少?

2023南阳中考满分多少?2023年中招学业成绩总分值为700分。继续实行初中

2023开封关于规范完善城乡居民门诊统筹工作的通知 观天下

一、提高筹资标准将门诊统筹基金筹资标准由原来的132元提高到每人每年1

2023开封城乡居民门诊统筹基金调整最新

开封市将门诊统筹基金筹资标准由原来的132元提高到每人每年146元,其中

中国台球协会:将从严处罚旅英涉赌球员 开展全行业警示教育|天天报道

新华社北京6月7日电(记者郑直 梁金雄)世界职业台球和斯诺克协会

2亿像素人像+零风险调光护眼屏 荣耀90系列2499元火热起售

6月7日,荣耀90系列全渠道同步开售。荣耀90和荣耀90Pro的起售价格分别

天天新消息丨聚焦智能物流装备和解决方案,中科微至发展前景可期

随着物联网、大数据、人工智能等前沿信息技术的发展,智慧物流已经成为

“高考加油!”贝克汉姆祝福中国考生,说起了中文

中新网6月6日电 “高考加油!”2023年中国高考即将拉开帷幕之际,

伊朗驻沙特大使馆重新开馆|全球观速讯

6月6日,在沙特阿拉伯利雅得,伊朗副外长比格德利(前)、沙特副外

4平方铜线电流是多少大卡_4平方铜线电流|环球播报

1、一般而言,4平方铜线最大承载电流是30A。2、这个和电缆的使用场合,

注册淘宝店铺全过程_注册淘宝

1、(☆本贴由尐杨公馆℡①提供,请勿随意转帖☆)淘宝网怎么注册会员流

手机充电器头怎么拆开_手机充电器头

1、手机充电快慢与充电器的头和线都有有关,特别是充电线。2、手机充电

业界:减辣可助提振经济

香港文汇报报导,政府接连出招加速经济复常,业界认为应包括尽快为楼市

宝妈专属出行利器,开全新一代瑞虎3x稳了!

宝妈一族正在成为新兴消费群体,她们思想独立、需求多元,特别是生活场景更为复杂。如今恰逢六一儿童节,如果有一辆趁手的座驾陪伴,不仅可

世界关注:新乡市教育局“微爱志愿者服务站”正式投入使用

为推动新乡市文明城市创建工作深入开展及市教育局志愿服务活动制度化、

当前快报:药师帮通过港交所上市聆讯 “营销及推广费用”收缩至15%

药师帮通过港交所上市聆讯“营销及推广费用”收缩至15%

当前热门:6月7日汇市观潮:欧元、英镑和澳元技术分析

6月7日汇市观潮:欧元、英镑和澳元技术分析

前5个月固收类银行理财品平均年化收益率达4.4% 天天百事通

证券时报网讯,广州日报获悉,今年前5个月固收类理财平均年化收益率达4

每日头条!暗黑破坏神4各职业过渡威能获取指南

会有很多暗黑破坏神4用户还不了解暗黑破坏神4各职业过渡威能获取指南,

天天热门:《暗黑破坏神4》炮台冰法流推荐 炮台冰法流怎么玩?

暗黑破坏神4开启了正式公测,这次玩家可以顺畅体验游戏的所有内容,为

天天速看:ChatGPT之父:OpenAI暂时没有上市计划

来源:华尔街见闻OpenAI创始人SamAltman明确表示,他对上市不感兴趣。

纽约取代香港成全球外派人员生活成本最贵城市,北上广排名下滑

根据ECA最新发布的2023年国际生活成本排名,纽约超越香港,成为全球外

综合资讯

+更多

热点资讯

+更多
股票账户的钱会不会突然消失?股票钱什么时候能转出?
股票账户的钱会不会突然消失?股票账户钱不会无缘无故消失,股票账户钱其实是存在银行而非券商,银行肯定是正规的地方,只要存的钱在里面就 [详细]

Copyright @ 2008-2020  www.43710.com   All Right Reserved Powered by 财经情报网 版权所有

财经情报网   联系邮箱:562 66 29@qq.com

网站备案:沪ICP备2020036824号-12