Solon v3.5.0

solon-statemachine

</> markdown

此插件,由社区成员(王奇奇)贡献

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-statemachine</artifactId>
</dependency>

1、描述

(v3.4.3 后支持)基础扩展插件,Solon 状态机(不需要持久化,通过上下文传递),作为 solon-flow 的互补。 主要用于管理和优化应用程序中的状态转换逻辑,通过定义状态、事件和转换规则,使代码更清晰、可维护。其核心作用包括:简化状态管理、提升代码可维护性、增强业务灵活性等。

核心概念包括:

  • 状态(State):代表系统中的某种状态,例如 "已下单"、"已支付"、"已发货" 等。
  • 事件(Event):触发状态转换的事件,例如 "下单"、"支付"、"发货" 等。
  • 动作(Action):在状态转换发生时执行的操作或行为。
  • 转换(Transition):定义状态之间的转换规则,即在某个事件发生时,系统从一个状态转换到另一个状态的规则

2、主要接口

接口说明
Event事件接口
EventContext事件上下文接口
EventContextDefault事件上下文接口默认实现
State状态接口
StateMachine状态机(不需要持久化,通过上下文传递)
StateTransition状态转换器
StateTransitionContext状态转换上下文
StateTransitionDecl状态转换说明(声明)

3、StateTransitionDecl 状态转换(DSL)说明

主要方法说明:

方法要求说明
from必须转换的源状态(可以有多个)
to必须转换的目标状态(一个)
on必须触发事件(当事件发生时,触发转换)
when可选额外条件
then可选然后执行动作

转换声明示例:

//t.from(oldState).to(newState).on(event).when(?).then(...) //when, then 为可选
addTransition(t ->
    t.from(OrderState.NONE).to(OrderState.CREATED).on(OrderEvent.CREATE).then(ctx -> {
        Order payload = ctx.getPayload();
        payload.setStatus("已创建");
        payload.setState(OrderState.CREATED);
        System.out.println(payload);
    }));

4、应用示例

准备相关类

/**
 * 订单事件枚举
 */
public enum OrderEvent implements Event {
    CREATE, PAY, SHIP, DELIVER, CANCEL;
}

/**
 * 订单状态枚举
 */
public enum OrderState implements State {
    NONE,CREATED, PAID, SHIPPED, DELIVERED, CANCELLED;
}

/**
 * 订单 (直接实现事件上下文,仅供参考)
 */
public class Order implements EventContext<OrderState, Order>{
  ...
}

/**
* 订单状态机
*/
public class OrderStateMachine extends StateMachine<OrderState, OrderEvent, Order> {
    public OrderStateMachine() {
        // 无 -> 创建订单
        this.addTransition(t ->
                t.from(OrderState.NONE).to(OrderState.CREATED).on(OrderEvent.CREATE).then(ctx -> {
                    Order payload = ctx.getPayload();
                    payload.setStatus("已创建");
                    payload.setState(OrderState.CREATED);
                    System.out.println(payload);
                }));

        // 创建 -> 支付
        this.addTransition(t ->
                t.from(OrderState.CREATED).to(OrderState.PAID).on(OrderEvent.PAY).then(ctx -> {
                            Order payload = ctx.getPayload();
                            payload.setStatus("已支付");
                            payload.setState(OrderState.PAID);
                            System.out.println(payload);
                        }
                ));

        // 支付 -> 发货
        this.addTransition(t ->
                t.from(OrderState.PAID).to(OrderState.SHIPPED).on(OrderEvent.SHIP).then(ctx -> {
                            Order payload = ctx.getPayload();
                            payload.setStatus("已发货");
                            payload.setState(OrderState.SHIPPED);
                            System.out.println(payload);
                        }
                ));


        // 发货 -> 送达
        this.addTransition(t ->
                t.from(OrderState.SHIPPED).to(OrderState.DELIVERED).on(OrderEvent.DELIVER).then(ctx -> {
                            Order payload = ctx.getPayload();
                            payload.setStatus("已送达");
                            payload.setState(OrderState.DELIVERED);
                            System.out.println(payload);
                        }
                ));
    }
}

应用测试

public class StatemachineTest {
    @Test
    public void test() {
        OrderStateMachine stateMachine = new OrderStateMachine();

        Order order = new Order("1", "iphone16 pro max", null);

        stateMachine.sendEvent(OrderEvent.CREATE, order); //使用定制事件上下文
        stateMachine.sendEvent(OrderEvent.PAY, order);
        stateMachine.sendEvent(OrderEvent.SHIP, EventContext.of(order.getState(),  order)); //使用内置上下文
        stateMachine.sendEvent(OrderEvent.DELIVER, EventContext.of(order.getState(),  order));
    }
}