有限状态机实现-状态机介绍

这个系列最终实现的状态机并不是一个标准的状态机,把状态机的很多标准的概念进行了简化,对概念的东西做了减法,实现了具备基本功能的状态机(很多所谓状态机更高级的功能,如:伪态,也可以在基本功能实现)。整个状态机的实现将分为下面几个章节介绍

  • 状态机介绍
  • 简单有限状态机的实现
  • 简单有限状态机的应用实例
  • 简单状态机功能增强
  • 有限状态机状态持久化设计
  • 有限状态机持久化实现
    当前章节以理论为主

有限状态机概念

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

  • 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版本有要求,有生产需求的同学也可以考虑一下


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 143,906评论 1 305
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 61,698评论 1 257
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 95,242评论 0 213
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 41,257评论 0 182
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 49,076评论 1 260
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 38,912评论 1 178
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,509评论 2 274
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,255评论 0 168
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 29,145评论 6 235
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 32,613评论 0 214
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,376评论 2 216
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 30,733评论 1 231
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 24,287评论 0 32
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,196评论 2 213
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 31,644评论 3 211
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,651评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,059评论 0 169
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 33,644评论 2 233
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 33,789评论 2 237

推荐阅读更多精彩内容

  • 状态机是无论科研探索还是科技应用方面都非常重要的一种分析工具。几乎在所有涉及到随时间演化的问题中,都可以找到状态机...
    Esmool阅读 3,958评论 0 26
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,390评论 25 707
  • 周检视第2周(2017年12月3~12月9日) 没有记录就没有发生—— 健康:1)泡脚7/7天 2)徒步45000...
    圆圆jXY阅读 136评论 0 0
  • 今天早上看见黄老师发的早晨三件事的分享,具体如下:什么是真朋友?有一个简单粗暴的标准:能开诚公布地谈钱的。朋...
    赵小杰呀阅读 254评论 2 0
  • DOM:文档对象模型,以节点树的方式描绘HTML或XML文档 DOM0:未正式成为公认标准前的DOM DOM1:W...
    pingink阅读 1,620评论 0 0