一、cola-statemachine介绍
COLA框架的状态机组件是一种轻量级的、无状态的、基于注解的状态机实现,可以方便地管理订单等业务对象的状态转换。COLA框架的状态机使用了连贯接口(Fluent Interfaces)来定义状态和事件,以及对应的动作和检查。COLA框架的状态机是COLA 4.0应用架构的一部分,旨在控制复杂度,提高开发效率。
COLA框架的状态机的优势有以下几点:
- 简化了状态转换的逻辑,避免了大量的if-else判断
- 提高了代码的可读性和可维护性,方便了单元测试和重构
- 支持多种状态机模式,如同步、异步、延迟等
- 与COLA框架的其他组件协同工作,实现领域驱动设计和六边形架构
二、COLA状态机的核心概念
- State:状态
- Event:事件,状态由事件触发,引起变化
- Transition:流转,表示从一个状态到另一个状态
- External Transition:外部流转,两个不同状态之间的流转
- Internal Transition:内部流转,同一个状态之间的流转
- Condition:条件,表示是否允许到达某个状态
- Action:动作,到达某个状态之后,可以做什么
- StateMachine:状态机
三、使用状态机
1. 环境配置
我的配置:
Maven: 3.6.3
SDK: 17
Language level:8
引入依赖:
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-statemachine</artifactId>
<version>4.3.1</version>
</dependency>
2. cola状态机的三种transition方式
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、接口方法说明
a. StateMachineBuilder
StateMachineBuilder方法 | 说明 |
---|---|
ExternalTransitionBuilder<S, E, C> externalTransition() | 用于一个流转的构建器 |
ExternalTransitionsBuilder<S, E, C> externalTransitions() | 用于多个流转的构建器 |
InternalTransitionBuilder<S, E, C> internalTransition() | 开始构建内部流转 |
StateMachine<S, E, C> build(String machineId) | 对状态机开始构建,并在StateMachineFactory中注册 |
b. StateMachine
StateMachine方法 | 说明 |
---|---|
boolean verify(S sourceStateId, E event) | 验证一个事件E是否可以从当前状态S触发 |
S fireEvent(S sourceState, E event, C ctx) | 向状态机发送一个事件E,触发状态机,并返回目标状态 |
String getMachineId() | 获取状态机的标识符MachineId |
void showStateMachine() | 使用访问者模式来显示状态机的结构 |
四、简单场景使用演示
0. 订单流程模拟(基本配置)
// 订单状态(States)
enum OrderState {
INIT,
PAID,
DELIVERED,
REFUNDED;
}
// 订单事件(Events)
enum OrderEvent {
PAY_SUCCESS,
PAY_FAIL,
DELIVERED_SUCCESS,
REFUND_SUCCESS;
}
// 订单(Context)
static class Order {
String operator = "frank";
String orderId = "123465";
}
static String MACHINE_ID = "orderStateMachine";
1. 外部状态流转(单个起始状态)
外部过程描述:起始状态INIT,结束状态PAID,当发生PAY_SUCCESS时执行状态流转,当满足checkCondition()时,执行doAction,执行成功则返回状态PAID,否则返回INIT
@Test
public void testExternalNormal(){
// 第一步:生成一个状态机builder
StateMachineBuilder<OrderState, OrderEvent, Order> builder = StateMachineBuilderFactory.create();
// 第二步:设置一个外部状态转移类型的builder,并设置from\to\on\when\perform
builder.externalTransition()
.from(OrderState.INIT)
.to(OrderState.PAID)
.on(OrderEvent.PAY_SUCCESS)
.when(checkCondition())
.perform(doAction());
// 第三步:设置状态机的id,并在StateMachineFactory中的stateMachineMap进行注册
StateMachine<OrderState, OrderEvent, Order> stateMachine = builder.build(MACHINE_ID);
// 第四步:触发状态机
OrderState target = stateMachine.fireEvent(OrderState.INIT, OrderEvent.PAY_SUCCESS, new Order());
assertEquals(OrderState.PAID, target);
}
a. checkCondition(示例)
private Condition<Order> checkCondition() {
return order -> {
System.out.println("Check condition : " + order);
return true;
};
}
方法体中使用了lambda表达式来创建一个Condition的实例,并返回它
b. doAction(示例)
private Action<OrderState, OrderEvent, Order> doAction() {
return (from, to, event, ctx) -> {
System.out.println(
ctx.operator + " is operating " + ctx.orderId + " from:" + from + " to:" + to + " on:" + event));
};
}
这段代码定义了一个私有方法,返回一个Action对象,该对象是一个函数式接口,接受四个参数:from, to, event, ctx,并执行一些逻辑。
- from: 表示状态转移的源状态
- to: 表示状态转移的目标状态
- event: 表示触发状态转移的事件
- ctx: 表示状态机的上下文对象
这个Action对象的逻辑是打印出一条信息,显示操作者、实体ID、源状态、目标状态和事件。例如:
frank is operating 123456 from:INIT to:PAID on:PAY_SUCCESS
这样可以方便地跟踪和调试状态机的运行情况。
2. 内部状态流转
内部过程描述:这个内部转换发生在PAID状态下,当发生DELIVERED_SUCCESS时执行状态流转,当满足checkCondition()时,执行doAction,执行成功则返回状态PAID文章来源:https://www.toymoban.com/news/detail-449460.html
@Test
public void testInternalNormal(){
StateMachineBuilder<OrderState, OrderEvent, Order> builder = StateMachineBuilderFactory.create();
builder.internalTransition()
.within(OrderState.PAID)
.on(OrderEvent.DELIVERED_SUCCESS)
.when(checkCondition())
.perform(doAction());
StateMachine<OrderState, OrderEvent, Order> stateMachine = builder.build(MACHINE_ID + "1");
OrderState target = stateMachine.fireEvent(OrderState.PAID, OrderEvent.DELIVERED_SUCCESS, new Order());
assertEquals(OrderState.PAID, target);
}
3. 外部状态流转(多个起始状态)
外部过程描述:起始状态PAID或DELIVERED,结束状态REFUNDED,当发生REFUND_SUCCESS时执行状态流转,当满足checkCondition()时,执行doAction,执行成功则返回状态REFUNDED,否则返回对应起始状态文章来源地址https://www.toymoban.com/news/detail-449460.html
@Test
public void testExternalTransitionsNormal(){
StateMachineBuilder<OrderState, OrderEvent, Order> builder = StateMachineBuilderFactory.create();
builder.externalTransitions()
.fromAmong(OrderState.PAID, OrderState.DELIVERED)
.to(OrderState.REFUNDED)
.on(OrderEvent.REFUND_SUCCESS)
.when(checkCondition())
.perform(doAction());
StateMachine<OrderState, OrderEvent, Order> stateMachine = builder.build(MACHINE_ID + "2");
OrderState target = stateMachine.fireEvent(OrderState.PAID, OrderEvent.REFUND_SUCCESS, new Order());
assertEquals(OrderState.REFUNDED, target);
}
4. 多个流转组合
@Test
public void testExternalInternalNormal(){
StateMachineBuilder<OrderState, OrderEvent, Order> builder = StateMachineBuilderFactory.create();
builder.externalTransition()...
builder.internalTransition()...
builder.externalTransition()...
builder.externalTransitions()...
StateMachine<OrderState, OrderEvent, Order> stateMachine = builder.build(MACHINE_ID + "3");
}
五、相关链接
- 相关Maven引用地址:https://search.maven.org/search?q=g:com.alibaba.cola
- 实现一个状态机引擎,教你看清DSL的本质:https://blog.csdn.net/significantfrank/article/details/104996419
- 阿里开源COLA 4.0 - 项目实践:https://www.jianshu.com/p/6a00d6912f45
- COLA下的cola-statemachine状态机:https://www.jianshu.com/p/895047a04ae5
到了这里,关于COLA中的cola-statemachine状态机理解与使用例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!