状态机理解

有限状态机概念

有限状态机简称就是状态机,因为一般的状态机的状态都是离散和可举的,即为有限,所以后面的介绍都不加有限二字。状态机表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。通俗的描述状态机就是定义了一套状态変更的流程:状态机包含一个状态集合,定义当状态机处于某一个状态的时候它所能接收的事件以及可执行的行为,执行完成后,状态机所处的状态。所以状态机会包含以下几个重要的元素:

  • State:状态。一个标准的状态机最少包含两个状态:初始和终态。初态是状态机初始化后所处的状态,而终态顾名思义就是状态机结束时所处的状态。其他的状态都是一些流转中停留的状态。标准的状态机还会涉及到一些中间态,存在中间态的状态机流程就会比较复杂(用处也不是特别大,而且可以通过其他方式实现),所以在目标实现的状态机里不会引入这个概念。
  • Event:事件。还有中描述叫Trigger,表达的意思都一样,就是要执行某个操作的触发器或口令:当状态机处于某个状态时,只有外界告诉状态机要干什么事情的时候,状态机才会去执行具体的行为,来完成外界想要它完成的操作。比如出去吃饭,说“点菜”,服务员才会拿着小本过来记录你要吃的菜,说的那句“点菜”,就相当于Event。
  • Action:行为。状态变更索要执行的具体行为。还是拿上面点菜的例子,服务员拿小本记录你定的菜的过程就是Action
  • Transition:变更。一个状态接收一个事件执行了某些行为到达了另外一个状态的过程就是一个Transition。定义Transition就是在定义状态机的运转流程。

状态图

上图就是一个最简单的状态机,一个初态,一个流转状态,一个终态,初态到流状态是不需要任何操作的,State1当发生了Event1事件时,执行Action1到达了终态。(我们最终实现的状态机,会把初态和终态都当做一个流状态来对待)。

说了这么多,状态机能干什么?状态机主要的应用场景就是流程控制。一个状态机定义以后,在某个状态下就只接收固定的Event,也就是执行指定的操作,这样流程就能按照预期定义的那样流转,不会出现乱入的情况,执行了一些在某状态下不允许执行的操作。一个很典型的应用就是工作流引擎:以工作流中典型的审批流程为例,审批流程按照预先定义的流程流转的固定的某些人手里,只有这一批固定的人才能审批,当审批后(可能是一个人审批,也可能是多个人审批)才会流转到下个节点,由下个节点的审批人继续审批,一直流转到最后一个节点。状态机的流转可以人工干预,也可以自动流转。定义为自动流转后,把业务流程定义完成后,只要添加一个定时任务,整个流程的运转就都由状态机来完成了。此外,当状态机加入了持久化操作后,所有的状态流转都会落地,当业务出现异常,方便定位问题,当流程定义的足够细粒度的话,还可以通过驱动状态机来实现重入,恢复异常的节点。

状态模式

在实现状态机之前,我们顺便简单的看一下设计模式中的状态模式,这个模式跟我们实现状态机的代码结构还是有一定的关系的。

状态模式:封装基于状态的行为,并将行为委托到当前的状态。

试想一下,现在有一种业务场景存在多个状态,比如一个要遭受攻击的游戏人物,当人物遭受攻击后我们要减少人物的血量,而当前人物可能处于的状态有如下(游戏中常见的一些场景):刚复活(对一切攻击免疫),正常状态,物理攻击免疫,魔法攻击免疫,攻击随机无效,各种叠加态。当攻击来了,人物该怎么掉血。在非使用状态模式的情况下,一种常见的写法,人物接受攻击,然后开始各种判断现在人物所处于的状态,各种if...else,当新的需求来额时候,就修改这些if...else。而采用状态模式,行为委托类保存着当前人物所处的状态,当攻击来了,委托类会把该攻击交由持有的状态来处理,实现了对修改关闭,对扩展开放。类图如下(具体就不上代码了,感兴趣的可以自己研究一下):

状态模式

  • Context:可以理解为上下文,它持有当前的状态,同时对外暴露状态行为接口
  • State:定义了状态下的行为接口
  • ConcreteState:行为接口的具体实现

其中Context是一个关键,在我们将要实现的状态机里扮演者重要的角色。
此外我们将要的实现的状态机远远不是一个状态模式的一个实现,要比它复杂的多。

目标状态机功能介绍

  • 状态机的定义:通过定义State,Event,Action,Transition来实现状态机的流转,摒弃标准状态机中那些较复杂的概念(通过其他方式来实现所谓的较复杂的操作)
  • 状态持久化:数据持久化到数据库,实现状态机的中断重启
  • 上下文保存与传递:提供一套流程流转过程中参数的传递机制
  • 并发控制:提供不同状态机隔离,同一状态机单实例运行机制
  • 功能增强:接口或注解的形式实现自触发,重试,定时执行

github上有一开源状态机,算是github上状态机系列java得星最多的项目,功能已经做的很强大,本人早期的时候关注过,但是到目前为止已经做的很复杂了,超出了大部分常规的使用场景,而且几个版本下来,代码风格也有了很大的变化。感兴趣的同学可以先看一下:
https://github.com/hekailiang/squirrel

此外Spring也有一套状态机,但对spring版本有要求,有生产需求的同学也可以考虑一下

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
generator(生成器)是一种特殊的函数,它能够在执行过程暂停和恢复。这一机制使得生成器在按需生成数据时非常有用,尤其是在处理大量数据或需要延迟计算的情况下。 generator的工作原理基于状态机。每次调用生成器函数时,它会返回一个迭代器对象。这个迭代器对象可以用于迭代生成器函数的运行结果。生成器函数会从最开始的状态开始执行,直到遇到一个“yield”关键字。一旦遇到“yield”,函数会将yield后面的值返回给调用者,并暂停执行。这个yield后面的值可以被提取并处理。 生成器函数的执行状态会被保留下来,这样在下一次调用生成器的时候可以恢复到上一次暂停的地方。这意味着每次调用生成器时,它会从上一次暂停的位置继续执行,直到遇到下一个yield关键字或者函数结束。 这种生成器机制能够有效地减少内存消耗,因为生成器每次只生成一个值,并且不需要将所有结果都保存在内存。生成器可以按需生成数据,并且只在需要时进行计算。这对于需要处理大型数据集或者运行时间较长的计算非常有帮助。 总结来说,generator状态机是一种特殊的函数,它能够在执行过程暂停和恢复。它基于状态机的原理,可以按需生成数据,并减少内存消耗。这种机制在处理大量数据或者需要延迟计算时非常有用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值