一.基本介绍
概念介绍
1.COLA框架的状态机组件是一种轻量级的、无状态的、基于注解的状态机实现,可以方便地状态流转业务对象的状态转换。
2.COLA框架的状态机使用了连贯接口(Fluent Interfaces)来定义状态和事件,以及对应的动作和检查,并却保了先后顺序,保证了代码的可读性。
状态机DSL(Domain Specific Languages)带来的表达能力,相比较于if-else的代码要更优雅更容易理解。
核心属性
State:状态
Event:事件,状态由事件触发,引起变化
Transition:流转,表示从一个状态到另一个状态
External Transition:外部流转,两个不同状态之间的流转
Internal Transition:内部流转,同一个状态之间的流转
Condition:条件,表示是否允许到达某个状态
Action:动作,到达某个状态之后,可以做什么
二.使用介绍
1.依赖引入
<dependency>
<groupId>com.alibaba.cola</groupId>`
<artifactId>cola-component-statemachine</artifactId>`
<version>4.3.1</version>
</dependency>
2.Fluent Interfaces接口
StateMachineBuilder<States, Events, Context> builder = StateMachineBuilderFactory.create();
//external transition
builder.externalTransition()
.from(States.STATE1)
.to(States.STATE2)
.on(Events.EVENT1)
.when(checkCondition())
.perform(doAction());
//internal transition`
builder.internalTransition()`
.within(States.STATE2)
.on(Events.INTERNAL_EVENT)
.when(checkCondition())
.perform(doAction());
//external transitions
builder.externalTransitions()
.fromAmong(States.STATE1, States.STATE2, States.STATE3)`
.to(States.STATE4)
.on(Events.EVENT4)
.when(checkCondition())
.perform(doAction());
` builder.build(machineId);
StateMachine<States, Events, Context> stateMachine = StateMachineFactory.get(machineId);`
stateMachine.showStateMachine();
3.触发状态机执行
OrderState target = stateMachine.fireEvent(States.STATE1, Events.EVENT4, ``new Order()); |
|---|
核心方法介绍
StateMachineBuilder
| StateMachineBuilder方法 | 说明 |
|---|---|
| ``` | |
| ExternalTransitionBuilder<S, E, C> externalTransition() |
| ```
ExternalTransitionsBuilder<S, E, C> externalTransitions()
``` | 用于多个流转的构建器 |
| ```
InternalTransitionBuilder<S, E, C> internalTransition()
``` | 开始构建内部流转 |
| ```
StateMachine<S, E, C> build(String var1)
``` | 对状态机开始构建,并在StateMachineFactory中注册 |
### StateMachine
| ### StateMachine方法 | 说明 |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| boolean verify(S sourceStateId, E event) | 验证一个事件E是否可以从当前状态S触发 |
| S fireEvent(S sourceState, E event, C ctx) | 向状态机发送一个事件E,触发状态机,并返回目标状态 |
| ```
String generatePlantUML()
``` | @startuml STATE1 --> STATE1 : EVENT1 STATE1 --> STATE2 : EVENT1 STATE1 --> STATE3 : EVENT1 @enduml![]() |
| void showStateMachine() | 使用访问者模式来显示状态机的结构from:1 to:2 on:event condition:100 -----StateMachine:11------- State:1 Transition:1-[event, EXTERNAL]->2 State:2 ------------------------ |
## 三.简单场景模拟
| `@Test``public` `void` `testExternalNormal(){`` ``// 第一步:生成一个状态机builder`` ``StateMachineBuilder<Integer, String, Integer> builder = StateMachineBuilderFactory.create();`` ``// 第二步:设置一个外部状态转移类型的builder,并设置from\to\on\when\perform`` ``builder.externalTransition()`` ``.from(``1``)`` ``.to(``2``)`` ``.on(``"event"``)`` ``.when(check())`` ``.perform(doAction());` ` ``// 第三步:设置状态机的id和ready,并在StateMachineFactory中的stateMachineMap进行注册`` ``StateMachine<Integer, String, Integer> stateMachine = builder.build(``"11"``);`` ``// 第四步:触发状态机`` ``Integer target = stateMachine.fireEvent(``1``, ``"event"``, ``100``);`` ``String s = stateMachine.generatePlantUML();`` ``Assert.assertEquals(target.intValue(), ``2``);``}` `private` `Condition<Integer> check() {`` ``return` `(ctx) -> {`` ``System.out.println(``"1"``);`` ``return` `true``;`` ``};``}` `private` `Action<Integer, String, Integer> doAction() {`` ``return` `(from, to, event, ctx)->{`` ``System.out.println(``"from:"``+from+``" to:"``+to+``" on:"``+event+``" condition:"` `+ ctx);`` ``};``}` |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
## 五.优缺点总结
优点总结如下:
1.代码简单,易于学习,便于根据我们的业务线基础上做二次开发。
2.无状态,减少内存消耗,线程先天安全。
3.先天支持事务
4.先天会自己抛出异常,不会像spring stateMachine出现将异常吃掉情况(当然通过反射确实可以将异常抛出)。
5.包小,摒弃了spring stateMachine中没有必要的功能,功能相对单一,包自然就小了。同时减少了资源的浪费。
## 六.源码解析,实现原理
<https://www.processon.com/view/link/64784de92d286d12cd074c31>