为什么选择COLA State Machine ?
状态机实现 | Spring State Machine | COLA State Machine |
---|---|---|
是否有状态 | 是 | 否 |
功能完备情况 | 功能完备 | 核心功能完备 |
学习难度 | 难 | 简单 |
性能 | 低 | 高 |
是否支持导出 PlantUML | 否 | 是 |
选型结果
结合公司订单系统的状态流转的业务需求。发现 COLA State Machine 足够满足当前的业务需求且性能强劲,较低的学习成本能够使得业务快速落地。
COLA State Machine 快速上手
概念:
Event:事件,状态由事件触发,引起变化
Transition:流转,表示从一个状态到另一个状态
External Transition:外部流转,两个不同状态之间的流转
Internal Transition:内部流转,同一个状态之间的流转
Condition:条件,表示是否允许到达某个状态
Action:动作,到达某个状态之后,可以做什么
StateMachine:状态
Integrate Spring Boot 2.x with COLA State Machine
添加依赖到POM文件:
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-statemachine</artifactId>
<version>4.3.1</version>
</dependency>
初始化 State Machine
import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.Condition;
import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.StateMachineFactory;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory;
import com.giga.statemachine.enums.GigaEvents;
import com.giga.statemachine.enums.GigaStates;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* StateMachineInit
*
* @author: Aiden.gong
* @since: 2023/1/10 11:25
*/
@Component
public class StateMachineInit {
public static String MACHINE_ID = "TestStateMachine";
/**
* Init state machine instance.
*/
@PostConstruct
private void initStateMachine() {
buildStateMachine(MACHINE_ID);
}
private StateMachine<GigaStates, GigaEvents, StateMachineContext> buildStateMachine(String machineId) {
StateMachineBuilder<GigaStates, GigaEvents, StateMachineContext> builder = StateMachineBuilderFactory.create();
builder.externalTransition()
.from(GigaStates.STATE1)
.to(GigaStates.STATE2)
.on(GigaEvents.EVENT1)
.when(checkCondition())
.perform(doAction());
builder.internalTransition()
.within(GigaStates.STATE2)
.on(GigaEvents.INTERNAL_EVENT)
.when(checkCondition())
.perform(doAction());
builder.externalTransition()
.from(GigaStates.STATE2)
.to(GigaStates.STATE1)
.on(GigaEvents.EVENT2)
.when(checkCondition())
.perform(doAction());
builder.externalTransition()
.from(GigaStates.STATE1)
.to(GigaStates.STATE3)
.on(GigaEvents.EVENT3)
.when(checkCondition())
.perform(doAction());
builder.externalTransitions()
.fromAmong(GigaStates.STATE1, GigaStates.STATE2, GigaStates.STATE3)
.to(GigaStates.STATE4)
.on(GigaEvents.EVENT4)
.when(checkCondition())
.perform(doAction());
builder.build(machineId);
StateMachine<GigaStates, GigaEvents, StateMachineContext> stateMachine = StateMachineFactory.get(machineId);
// Generate the state machine graph for visualization
String plantUMLStr = stateMachine.generatePlantUML();
System.out.println(plantUMLStr);
return stateMachine;
}
private Condition<StateMachineContext> checkCondition() {
return context -> {
System.out.println("Check condition : " + context);
return context.getBusinessService().checkSomething();
};
}
private Action<GigaStates, GigaEvents, StateMachineContext> doAction() {
return (from, to, event, ctx) -> {
ctx.getBusinessService().doSomething();
System.out.println(
ctx.getOperator() + " is operating " + ctx.getEntityId() + " from:" + from + " to:" + to + " on:" + event);
};
}
}
查看State Machine 的 PlantUML
运行 com.giga.ColaStateMachineApplicationTests#testStateMachine 上述代码拷贝PlantUML字符串到 在线编写PlantUML 即可看到状态流转图:
我们可以很容易地根据 PlantUML 图来确认 State Machine 的状态流转是否与业务需求一致。
注意:
- 相同的 StateMachine instance 是单例。
- bean 作为 StateMachineContext 构造方法入参。
源码:
Github: https://github.com/GOODBOY008/cola-state-machine.git