支持的高阶功能有:状态的嵌套(substate) , 状态的并行(parallel , fork , join)、子状态机等等 。大家可以对照一下这些功能你是否用的到 。问题二:性能差
这些状态机都是有状态的(Stateful)的 , 有状态意味着多线程并发情况下如果是单个实例就容易出现线程安全问题 。在如今的普遍分布式多线程环境中 , 你就不得不每次一个请求就创建一个状态机实例 。但问题来了一旦碰到某些状态机它的构建过程很复杂 , 如果当下QPS又很高话 , 往往会造成系统的性能瓶颈 。在这里我给大家推荐一款阿里开源的状态机:cola-statemachine 。github地址:github.com/alibaba/COL…作者(张建飞:阿里高级技术专家)讲到面对复杂的状态流转 , 当时他们团队也想搞个状态机来减负 , 经过深思熟虑、不断类比之后他们考虑自研 。希望能设计出一款功能相对简单、性能良好的开源状态机;最后命名为cola-component-statemachine(实现了内部DSL语法;目前最新版本:4.3.1)
示例代码:
//构建一个状态机(生产场景下 , 生产场景可以直接初始化一个Bean)StateMachineBuilder<StateMachineTest.ApplyStates, StateMachineTest.ApplyEvents, Context> builder = StateMachineBuilderFactory.create(); //外部流转(两个不同状态的流转) builder.externalTransition() .from(StateMachineTest.ApplyStates.APPLY_SUB)//原来状态 .to(StateMachineTest.ApplyStates.AUDIT_ING)//目标状态 .on(StateMachineTest.ApplyEvents.SUBMITING)//基于此事件触发 .when(checkCondition1())//前置过滤条件 .perform(doAction());//满足条件 , 最终触发的动作复制代码上述代码先构建了一个状态机实例:from和to分别定义了源状态和目标状态 , on定义了一个事件(状态机基于事件触发)当状态机匹配到指定的事件后 , 会进行条件过滤 , 如果满足指定条件 , 就会执行perform定义的动作函数 , 最终状态会从from内的源状态变成to定义的目标状态 。我们一起来看看客户端是怎么触发自定义的状态机的:
复制代码StateMachine<StateMachineTest.ApplyStates, StateMachineTest.ApplyEvents, Context> stateMachine = builder.build("ChoiceConditionMachine");//fireEvent发送一个事件;对应上面示例代码的ApplyEvents.SUBMITING.StateMachineTest.ApplyStates target1 = stateMachine.fireEvent(StateMachineTest.ApplyStates.APPLY_SUB, StateMachineTest.ApplyEvents.SUBMITING, new Context("pass"));输出:from:APPLY_SUB to:AUDIT_ING on:SUBMITING condition:pass复制代码我把上述三款状态机的示例代码都放在了github上 , 有兴趣的小伙伴可以自行查阅 。github地址:
github.com/TaoZhuGongB…
总结好了 , 此篇文章即将进入尾声 , 让我们一起来做个总结 。
为什么引入状态机?
前言部分我也提到了在面对复杂的状态流转场景下if-else方案主要容易引起可读性、可扩展、易出错等问题 , 所以引入状态机主要为了降低这些风险 。
状态机的实现方案对比:
状态机实现方案我举例了Java枚举、状态模式、开源状态机等几个实现方案 。状态模式的问题是它需要定义接口、和实现类还附带一个Context上下文类 , 编码层面比较复杂 。Java枚举版的状态机主要问题是扩展粒度不够基本都是线性扩展 , 封装在一个类中 , 太复杂的状态流转这个类也会变得臃肿不堪 , 维护性变低 。所以也推荐了一款比较理想的开源状态机实现--cola-component-statemachine 。它使用相当简单 , 因为实现了内部DSL , 所以可读性很强 , 当然扩展性也比较不错 。
经验总结扩展阅读
- 如何快速减脂 如何快速减脂增肌
- Vue3 企业级优雅实战 - 组件库框架 - 4 组件库的 CSS 架构
- 2022年农历十月三十是乔迁的最佳吉日吗
- 篮球锻炼腿部肌肉的方法 篮球腿部训练方法
- MindSpore Graph Learning
- 提臀最快最好方法 提臀最快的方法
- 蝴蝶机夹胸的正确做法 蝴蝶机夹胸怎么做
- 运动量大的人具体吃什么 运动量大的人多吃什么
- 做减肥豆芽汤窍门 减肥豆芽汤的做法
- MySQL 是怎么加行级锁的?为什么一会是 next-key 锁,一会是间隙锁,一会又是记录锁?
