状态机的介绍和使用
状态机介绍
我们在开发过程中,发现一些场景优化可以很明显的使用状态机模式对模型进行状态的转移, 状态模式也是我们在开发的过程中常用的模式, 毕竟写起来很简单 ,有用一个枚举就可以表达. 该文章给大家介绍下状态机相关的知识点
状态模式
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式。状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。
状态模式所涉及到的角色有:
- 环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
- 抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的
- 具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。
状态模式demo
-
context
-
state
-
客户端
环境类Context的行为request()是委派给某一个具体状态类的。通过使用多态性原则,可以动态改变环境类Context的属性State的内容,使其从指向一个具体状态类变换到指向另一个具体状态类,从而使环境类的行为dorequest()由不同的具体状态类来执行。
状态机
状态机是状态模式的一种运用,是一组状态的集合,是协调相关信号动作,完成特定操作的控制中心。状态机可归纳为4个要素,即当前状态,条件,动作,下个状态。这样的归纳主要出于对状态机的内在因果关系的考虑,当前状态和条件是因,动作和下个状态是果。对于复杂些的逻辑,用状态机会有助于代码比较清晰,容易维护和调试
复杂度对比
在github上TOP2 的状态机是 spring 状态机 和 squirrel ,这2个开源框架功能都十分强大, 但是结合自身业务要求 ,其实用不上他们强劲的功能,反而在一些简单场景下,使用的上手难度反而增高,于是把目光投向了COLA state Machine,,在作者博客中有这种说法
在合适的地方用合适的解决方案,不能一招鲜吃遍天。就像最臭名昭著的DSL——流程引擎,就属于那种严重的被滥用和过渡设计的典型,是把简单的问题复杂化的典型。
最好不要无端增加复杂性。然而,想做简单也不是一件容易的事,特别是在大公司,我们不仅要写代码,还要能沉淀“NB的技术”,最好是那种可以把老板说的一愣一愣的技术
我所需要的状态机,也仅仅需要将状态转移并对数据进行持久化,使用复杂度当然是越简单越好了
性能优化对比
COLA状态机 还有一个概念,全程操作完全可以是无状态的, 市面上的开源状态机引擎,不难发现,它们之所以有状态,主要是在状态机里面维护了两个状态:初始状态(initial state)和当前状态(current state),如果我们能把这两个实例变量去掉的话,就可以实现无状态,从而实现一个状态机只需要有一个instance就够了。当然这样就没办法获取到状态机instance的current state,不过在我使用的过程中也不需要知道,这样一来,一个单例就可以维护整个状态的流程,性能大大提高
COLA状态机名词概念
- State:状态
- Event:事件,状态由事件触发,引起变化
- Transition:流转,表示从一个状态到另一个状态
- External Transition:外部流转,两个不同状态之间的流转
- Internal Transition:内部流转,同一个状态之间的流转
- Condition:条件,表示是否允许到达某个状态
- Action:动作,到达某个状态之后,可以做什么
- StateMachine:状态机
流程解析
COLA实现的状态机十分之简单,作者说是利用空余时间写的, 整体项目文件数量不超过30个,大部分都是interface,结构清晰易懂
- 结构图示
COLA 状态机demo
下面写了个demo展示.具体内容参考的是test源码中的内容
State枚举
Event枚举
context领域模型
客户端
以上代码执行后能清晰看到状态从INIT 状态转移到了WILL_SEND 状态,其中判断条件是啥.实用的场景
代码解析
首先是com.alibaba.cola.statemachine.builder.StateMachineBuilderImpl
构建出状态流转实体
后续,开始补充from
,to
,on
,perform
等方法,最后调用build
方法放入本地缓存,然后使用的时候去调用StateMachineFactory#get.fireEvent
注意一点的是在4.0.0
中有个坑
com.alibaba.cola.statemachine.impl.StateImpl
而在4.1.0 没有使用这种写法,而是使用的list避免了覆盖问题
这样整个流程就执行完了,整体结构比较小巧,也为我们在改编重构上提供了便利, 如结合srping容器,如添加注解形式的state Machine等.
参考文章
https://blog.csdn.net/significantfrank/article/details/104996419
__EOF__

本文链接:https://www.cnblogs.com/wzqshb/p/15716161.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗