随笔分类
spring-statemachine
状态机:从一种状态到另一种状态可预测的确定性转变,与之相关的便是动作
状态机实际上为我们提供了一种思考问题的方式,即状态是可更改的,而我们需要考虑的便是当前状态的含义是什么,什么情况下会触发状态的转变,状态之间的联系是怎样的?
基于 statemachine,我们可以摆脱那些烦人的 if-else if-else...
spring-statemachine便是状态机较好的落地实现框架之一,在配置好初始节点,启动状态机后,状态机便能够基于本地机器正常运行 single point,statemachine对其做了一些扩展,在配置状态机状态时,对指定状态进行定制化业务操作,如对订单而言,我们关注于其 Submitted、Paid、Fulfilled、Cancelled四个状态,那么我们可以针对这些状态节点自定义逻辑处理,在状态更变时将订单更变相关信息存放到上下文或者将其本身作为一种事件 Message传递到对应节点处理上,对应 Message,其 payload是对应事件,headers里头存放业务相关数据
但这只是单机下的玩法,生产环境下我们通常不会这么去玩,也很少去使用其提供的持久化的方式
对于状态机,清楚地一点便是一个状态是由前置状态以及前置动作唯一确立的,也就是说一个状态可能会有多个前置状态,区别点在于前置动作,因此对于状态节点,我们想要了解的便是:当前状态是由哪些状态节点以及动作转变过来的,以及后续状态及其动作有对应有哪些?
阅读 spring-statemachine手写实现了个简易版的状态机:
interestTools/spring-machine at master · tiandankanfeng/interestTools (github.com)
测试 demo:
/**
* @Author: 远道
* @Date: 2022-04-22 15:41
* @Description:
*/
public enum OrderEvents {
PAY,
FULFILL,
CANCEL;
}
public enum OrderStatus {
SUBMITTED,
PAID,
FULFILLED,
CANCELLED
}
@Test
public void testSelfStatemachine() {
StatemachineConfigurer<OrderStatus, OrderEvents> statemachineConfigurer
= new StatemachineConfigurer<>();
Statemachine<OrderStatus, OrderEvents> statemachine = statemachineConfigurer
.withExternal().setCurrent(OrderStatus.SUBMITTED).setNext(OrderStatus.PAID).setEvent(OrderEvents.PAY)
.and()
.withExternal().setCurrent(OrderStatus.PAID).setNext(OrderStatus.FULFILLED).setEvent(OrderEvents.FULFILL)
.and()
.withExternal().setCurrent(OrderStatus.SUBMITTED).setNext(OrderStatus.CANCELLED).setEvent(
OrderEvents.CANCEL)
.and()
.withExternal().setCurrent(OrderStatus.PAID).setNext(OrderStatus.CANCELLED).setEvent(OrderEvents.CANCEL)
.and()
.withExternal().setCurrent(OrderStatus.FULFILLED).setNext(OrderStatus.CANCELLED).setEvent(
OrderEvents.CANCEL)
.build();
List<OrderStatus> lastStates =
statemachine.getLastStates(OrderStatus.CANCELLED);
/**
* [SUBMITTED, PAID, FULFILLED]
*/
System.out.println(lastStates);
assertThat(statemachine.getNextStateByEvent(OrderStatus.PAID, OrderEvents.FULFILL), equalTo(OrderStatus.FULFILLED));
}