网站首页 > java教程 正文
无状态状态机
一:前言
在项目中经常有一些工单,申请之类需要对状态进行流转。这种需求一般都是满足什么条件然后就翻转状态。这些流程结构相似的逻辑,感觉可以抽象处理。用一个通用的结构处理,可以让系统更加整洁,代码逻辑更加单一。
? 发现阿里开源一种,轻量级的无状态状态机得组件。仔细研究一下,确实很适合这种场景下对代码逻辑的解耦,相比于if-else代码更加让人容易理解,也更加优雅。
二:状态机的模型
- State:状态
- Event:事件,状态由事件触发,引起变化
- Transition:流转,表示从一个状态到另一个状态
- External Transition:外部流转,两个不同状态之间的流转
- Internal Transition:内部流转,同一个状态之间的流转
- Condition:条件,表示是否允许到达某个状态
- Action:动作,到达某个状态之后,可以做什么
- StateMachine:状态机
三:怎么使用
? 这里我们假设几个简单的逻辑需要处理:
- 我们需要从待审核的状态需要流转到审核通过的状态,审核前需要做一个审核校验,审核通过后需要发送短信通知用户。
外部状态流转实现:
- 定义状态枚举(待审核,审核通过,拒绝)
static enum States {
WAITE, PASS, REJECT
}
- 定义一个事件枚举,审核事件/审核拒绝/提交申请/内部状态流转
static enum Events {
AUDIT, AUDIT_REJECT, COMMIT, COMPLETE_INFORMATION
}
// 上下文对象
static class Context{
String operator = "flw";
String entityId = "7758258";
}
- 按照上面需求配置一个状态机
StateMachineBuilder<States, Events, Context> builder = StateMachineBuilderFactory.create();
builder.externalTransition() // 外部状态流转
.from(States.WAITE) // 起始状态:待审核
.to(States.PASS) // 目的状态:审核通过
.on(Events.AUDIT) // 事件:审核事件
.when(checkCondition()) // 流转需要校验的条件,校验不通过不会进行doAction
.perform(doAction()); // 执行流转操作
StateMachine<States, Events, Context> stateMachine = builder.build(MACHINE_ID);
// 打印状态机里面的流程流转图谱
stateMachine.showStateMachine();
private Condition<StateMachineMyTest.Context> checkCondition() {
return (ctx) -> {return true;}; // 默认返回true
}
private Action<StateMachineMyTest.States, StateMachineMyTest.Events, StateMachineMyTest.Context> doAction() {
return (from, to, event, ctx)->{
System.out.println(ctx.operator+" is operating "+ctx.entityId+" from:"+from+" to:"+to+" on:"+event);
};
}
执行状态机的打印图谱结果:
-----StateMachine:TestStateMachine-------
State:PASS
State:WAITE
Transition:WAITE-[AUDIT, EXTERNAL]->PASS
------------------------
- 执行状态机
// 通过状态机执行 待审核状态执行审核操作,
States target = stateMachine.fireEvent(States.WAITE, Events.AUDIT, new Context());
Assert.assertEquals(States.PASS, target); // 成功就会返回目标状态机,校验失败就会返回原来的状态
执行结果:
flw is operating 7758258 from:WAITE to:PASS on:AUDIT
如果 checkCondition 返回false ,就不会执行doAction 操作。
内部状态流转实现
- 假设现在只是用户补全资料,只需要进行一些更新数据操作,不需要状态流转。这种需求可以通过内部状态流转实现
@Test
public void testExternalNormal(){
StateMachineBuilder<States, Events, Context> builder = StateMachineBuilderFactory.create();
builder.externalTransition()// 内部流转
.from(States.WAITE)
.to(States.PASS)
.on(Events.COMPLETE_INFORMATION)
.when(checkCondition())
.perform(doAction());
StateMachine<States, Events, Context> stateMachine = builder.build(MACHINE_ID);
// 打印状态机里面的流程流转图谱
stateMachine.showStateMachine();
// 通过状态机执行 待审核状态执行审核操作,
States target = stateMachine.fireEvent(States.WAITE, Events.AUDIT, new Context());
Assert.assertEquals(States.WAITE, target);
}
执行结果:
-----StateMachine:TestStateMachine-------
State:PASS
State:WAITE
Transition:WAITE-[COMPLETE_INFORMATION, EXTERNAL]->PASS
------------------------
对于方法里面的异常也会抛出来,也是支持事务操作。
整体的流程图如下:
四:总结
? 状态机非常轻量,支持事务操作,对于状态流转比较对的场景逻辑解耦还是比较优雅的。
- 上一篇: Java微服务实现订单状态机(业务,规划,设计,实现)
- 下一篇: 有限状态机
猜你喜欢
- 2024-11-26 Java线程调度&状态
- 2024-11-26 JAVA线程状态及实现
- 2024-11-26 学Java很久了,但越学越“糊涂”,Java学到什么程度才叫精通呢?
- 2024-11-26 设计模式之状态模式
- 2024-11-26 java开发工具IntelliJ IDEA Git使用教程:检查项目状态
- 2024-11-26 java设计模式状态模式
- 2024-11-26 Java线程的6种状态及切换,透彻讲解
- 2024-11-26 计算机等级二考试辅导:Java IO机试题及解答(第2部分)
- 2024-11-26 清华教授,手把手带你深度解读Java枚举,理论与实战齐飞
- 2024-11-26 Java试题分享211111
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)