找回密码
 立即注册
首页 业界区 业界 10分钟带你体验 Solon 的状态机

10分钟带你体验 Solon 的状态机

欤夤 昨天 21:00
一、介绍

Solon 状态机,称为 Solon State Machine。它是一种可以管理状态、事件之间的关系,以及他们之间的转换。这是一个专门为应用程序中的状态管理和状态转换提供支持的框架。
它简化了事物对象在不同状态下,不同事件转化的代码管理,让其代码变得更加清晰明了。
本文将介绍 Solon State Machine 状态机在 Solon 框架下的使用,10分钟带你理解并上手使用 Solon 状态机
二、状态机的核心概念

首先,我们必须要了解 Solon 状态机的几个核心概念,如下

  • 状态(State):代表着对象的当前状态
  • 事件(Event):对象状态转变是因何而改变的
  • 转换(Transition):定义了事物的状态是通过哪个事件变到了另一个状态
比如,最常见的就是订单系统,下面就简单模拟一下正常订单的状态流转:

  • 用户下单(状态为:待支付)
  • 用户支付成功(状态为:已支付待发货)
  • 仓库已发货(状态为:已发货待收货)
  • 用户成功收货(状态为:已收货)
三、代码

添加对应的 maven 依赖
  1. <dependency>
  2.     <groupId>org.noear</groupId>
  3.     solon-statemachine</artifactId>
  4.     <version>3.5.1</version>
  5. </dependency>
复制代码
对于状态,由于非常固定,我们最好是使用枚举,如下OrderStatus.java
  1. public enum OrderStatusEnum {
  2.     WAIT_PAY, //待支付
  3.     WAIT_DELIVER, //已支付待发货
  4.     WAIT_RECEIVE, //已发货待收货
  5.     RECEIVED; //已收货
  6. }
复制代码
还要定义一下事件的枚举
  1. public enum OrderStatusEventEnum {
  2.     ORDER, //用户下单
  3.     PAY, //用户支付成功
  4.     DELIVER, //仓库已发货
  5.     RECEIVE; //用户成功收货
  6. }
复制代码
接下来我们就能定义转换了,在 Solon 框架下,我们可以定义一个 OrderStateMachine 托管类
  1. @Managed
  2. public class OrderStateMachine extends StateMachine<OrderStatusEnum,OrderStatusEventEnum, OrderEntity> {
  3.     public OrderStateMachine() {
  4.         // 待支付 -> 已支付待发货(支付成功)
  5.         from(OrderStatusEnum.WAIT_PAY).to(OrderStatusEnum.WAIT_DELIVER)
  6.                 .on(OrderStatusEventEnum.PAY)
  7.                 .then(c -> c.getPayload().setStatus(c.getTo()));
  8.         // 已支付待发货 -> 已发货待收货(仓库已发货)
  9.         from(OrderStatusEnum.WAIT_DELIVER).to(OrderStatusEnum.WAIT_RECEIVE)
  10.                 .on(OrderStatusEventEnum.DELIVER)
  11.                 .then(c -> c.getPayload().setStatus(c.getTo()));
  12.         // 已发货待收货 -> 已收货(用户收货)
  13.         from(OrderStatusEnum.WAIT_RECEIVE).to(OrderStatusEnum.RECEIVED)
  14.                 .on(OrderStatusEventEnum.RECEIVE)
  15.                 .then(c -> c.getPayload().setStatus(c.getTo()));
  16.     }
  17. }
复制代码
是不是感觉还缺了什么呢,配置中还缺少一个下单事件,这没有关系,这是我们初始的一个事件,不参于配置
我们写对应的 OrderController 接口即可,这边模拟一下,创建订单进行落库
  1. @Controller
  2. public class OrderController {
  3.     @Mapping("/create")
  4.     public Result<Void> create() {
  5.         // TODO 模拟订单落库
  6.         return Result.succeed();
  7.     }
  8. }
复制代码
重点是在后面的,支付这一个阶段,我们应该如何接入状态机,如下
  1. @Controller
  2. public class OrderController {
  3.     @Inject
  4.     private OrderStateMachine orderStatusMachine;
  5.     @Mapping("/create")
  6.     public Result create() {
  7.         // TODO 模拟订单落库
  8.         return Result.succeed();
  9.     }
  10.     @Post
  11.     @Mapping("/pay")
  12.     public Result pay() {
  13.         // TODO 模拟订单支付
  14.         return Result.succeed();
  15.     }
  16.     @Post
  17.     @Mapping("/payNotify")
  18.     public Result payNotify(Integer orderId) {
  19.         // TODO 支付成功后,使用状态机
  20.         // 模拟通过id查找一个订单对象
  21.         OrderEntity entity = new OrderEntity(orderId, OrderStatusEnum.WAIT_PAY);
  22.         // 使用状态机发送这个消息
  23.         orderStatusMachine.sendEvent(OrderStatusEventEnum.PAY, EventContext.of(entity.getStatus(), entity));
  24.         return Result.succeed();
  25.     }
  26. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册