想法的力量今日看点程序员

状态机提要

2017-02-27  本文已影响762人  Esmool

状态机是无论科研探索还是科技应用方面都非常重要的一种分析工具。几乎在所有涉及到随时间演化的问题中,都可以找到状态机的用武之地。这里作为一个普及性的介绍文章,我们主要针对最基础形式的状态机进行一些深入浅出式的提要介绍,以期能够令读者对状态机有一定的基础认识,能够理解状态机分析方法的思考路线,并掌握一些最基本形式的状态机画法。

本文将会从三个主要角度展开介绍,分别为:

其中我们会用较大的篇幅进行状态以及状态机的概念辨析。因为在实际应用中,由于状态及状态机概念的错误理解而造成的绘图错误占了各种错误原因的极大比例,也是初学者最难逾越的最大难关。因此请读者无比潜心静气仔细理解这部分所展开的辨析,以便以后的使用中能够轻松应对。

一、现实中的状态机实例

在现实应用中,状态机的身影遍布科技应用的方方面面。从物理学中的物质三态转换关系


物质三态转化关系图

到环境科学中的碳循环


碳循环, 来自[wikipedia](https://en.wikipedia.org/wiki/Carbon_cycle)

从数字电路中的JK触发器


J-K 触发器状态图

图书馆藏书的生命周期分析


馆藏图书状态图

乃至保障我们天天上网所不可获取TCP网络通讯协议的实现状态图


TCP状态转换图

仅由上述寥寥数例,便可窥见状态机的广泛应用。

二、什么是状态、什么是状态机

日常语言中,状态一词的概念往往是人们通过反复大量的接触而建立的经验性归纳概念。一旦谈及状态,想要通过其内涵为它建立一个较为清晰的定义对普通人而言往往是似乎乎之欲出确有无法准确遣辞达意的一件事情。

在数学、物理学以及应用科学领域,各种不同的状态模型内都有自己关于对“状态”的看法,比较经典的例如

1. 一般化的状态定义及引申理解

然而,进一步厘清以获得一个更加一般化的关于状态的认识,对于我们准确理解状态机概念是十分必要的。在此,本文尝试就我们下面所要讨论的范围内的问题,提出一个相对抽象度更高的一个状态的概念,以便于后续的讨论。

下面请同作者一道,花一些时间纠结于“是”与“非”这类的问题上。请相信,概念的厘清将会为我们准确理解并运用状态机方法带来决定性的支撑。

__ 一个讨论对象的某些方面的特征在某些时刻,会具有同其它时刻之间相异的一些区别。刻画这种同一对象在不同时刻该方面特征间区别的工具即为状态,称之为该对象在的该方面特征的状态。 __

这个定义,其核心结构为

刻画……区别……的工具即为状态

同时通过三个限定结构

  • 同一对象

指出了状态概念的几个必备要件。

为了进一步帮助理解上述定义,可以考虑一下通过几个从此引申的辨析。

(1) 状态从属于一个特定的对象

不同对象的状态可能在取值上相等,但一定不是同一状态,因为它们的从属对象不同。

所谓同一状态,外在的表现必然是无论何时所取得值都是相等的。

例如

灯的颜色状态可能在某时是“红色”,苹果的颜色状态也可能在某时是“红色”,这种情况下两者的值是相等的。但显然红灯的颜色状态和红苹果的颜色状态不是同一个状态。它们的取值不会永远相等。

由此进一步引申的一个思考技巧是

讨论状态时必须明确无误的指明状态所从属的对象,且大多的语境下不应轻易变换这个从属对象

这里所谓的目标对象,可以是实际存在的物,也可能是某种事件、某种过程,而且在实际运用中后者居多。

例如

(2) 一个对象的状态可能随时间变化

一个对象的状态在不同时刻可能取不同的值,也可能取相同的值。但只要所讨论的对象没有变化、所讨论的方面没有变化,那么这个不同时刻的状态就没有在同一性上发生变化,而仅仅是取值可能发生了变化。

例如

电灯的工作状态在通电时是“亮”,在不通电时是“灭”。

** 状态随时间变化这个事实是整个状态机方法的中心要点,也正是因为这个,讨论状态才具有了它的必要性。**

状态取值随时间的变化,称为状态的流转。变化前的状态值称为流出状态,变化后的状态值称为流入状态

大多数的情况下,状态的流转并不是自发的,而是在满足某些条件的情况下触发的,这种触发条件称为事件。在没有发生指明的事件时,状态将会保持原有的值,直到触发事件发生。

例如

若一个状态取值在不同的条件下可能流转到不同的流入状态,那么这个状态的流转便是选择性的。

例如

考虑台式电话机的工作状态。若观察“话筒已提起”这个状态值,若发生“用户挂回话筒”事件,则话机的状态将转换为“已挂机”。但若发生“用户拨号”事件,那么话机状态则将进入“电话接通中”。

当然也存在无序任何触发条件而发生的自发性流转。这种情况下,流出状态将会是瞬时的,经历一个瞬间后便会转换为自发流转的流入状态。这种具有自发流转的流出状态,称为瞬态

实际上,这里的瞬间所指并不见得一定便是人类所能够体验的所谓足够短的时间。而是指对于所考察的问题,此种流转的条件是不被关心的。因此这个瞬间可能确实非常短,也可能实际上很长久。

例如

瞬态沿自发性流转变化是一个必然的过程。因此不存在统一个瞬态具有多条不同目的地的自发流转的情况。同样,瞬态上也不存在其它条件性流转的可能。瞬态只能具有一个唯一的自发性流转。

在大多数情况中,除非具有相当强烈的需求需要讨论瞬态本身同其对应的流入态之间的区别,否则单独设置一个瞬态是没有必要的,往往可以和之后的流入态进行合并处理。这是自发性流转和瞬态并不常见的原因。

(3) 一个对象的状态可以是连续变化的,也可能是跳跃取值离散变化的

例如

依照所考察的对象的状态的这种连续和离散取值的区别,可以比较简单的将状态机分为连续状态机离散状态机。而离散状态机中,又可根据可能出现的状态的总数量分为有限状态机无限离散状态机

例如

各种状态机的应用场景各不相同,在面对工作过程建模这类问题时,有限状态机是较为常用的。同时有限状态机也是使用状态图进行建模的过程方法论中最为基础的。作为入门性介绍文章,本文的介绍范围也限定于此。

(4) 状态机问题的讨论是基于考察时间范围、考察问题范围进行的

哲学上,对于任何一个对象,其能够用以表征不同时刻差异的特征是无穷多的。如果不考虑范围贪大求全,那么所考虑的状态集将会无穷大,将会超越人类的思维理解能力。因此,建模过程中,应当首先明确所考虑的问题范围,限定边界,以将复杂的问题化简、将不可能的问题转为可能。

同样,在时间上,对象的状态的可能值范围也是随时间变化的。若试图建立一个模型囊括对象所有时间上的情形,那么仍将会掉入无穷的陷阱。对于状态的建模,仍应采取宏观小+微观大的方案。选取合适的时间范围,即能够保证状态取值范围的稳定,又能够保证状态取值范围内所有值都具备取值的可能性(即状态取值范围内的遍历性)。

例如

未经专业训练的建模者在这个问题上是最易犯错的,往往担心考虑不足,不能够适度控制考察范围,而陷入了“吾生也有涯,而知也无涯 。以有涯随无涯,殆已。”的困境。数学本身的方法论中心思想是化简,人类的思维能力相对于茫茫知识的海洋,仅仅是一叶扁舟。面临超越自身能力范围的问题时,通过可靠的方法将其转化为若干较为简化而能够被处理的问题,这样才能最终解决问题。一步到位的做法永远仅仅只能起到望梅止渴的而已。切记!切记!

2. 状态机的概念、画法

如前文所述,状态机是指面对一个对象,针对所考察的状态,其所有可能状态取值以及这些状态取值之间的流转关系整体描述

状态机图则是进行上述描述的一种有效工具。当然,还存在其它描述方法,例如列表法、公式法等,不过本文仍将重点放在状态机图的使用上。

画法

例图

基本画法

这里特别需要将前述概括中的若干重点进行加强,以下分别说明。

(1) 一幅图之内应当仅讨论一个对象的状态

如前文所述,一个状态机表征的是唯一的对象,一幅状态机图应当仅绘制一个对象的状态流转。任何多余一个以上的对象的状态若出现在同一幅图中,均是概念混淆的错误。当对象状态结构较复杂时,可以用多幅图联合描述一个对象,但任何一个图中均应仅谈论这个对象。

例图

仅讨论一个对象的状态,若讨论的对象仅仅是灯具,那么右边的画法是正确的,而左边是错误的

(2) 目标对象的状态取值应当是有限的,一套图内应当画出所有状态取值

如前文所述,应当在限定的时间范围、限定的讨论范围内选择状态取值范围,而且针对我们所讨论的有限状态机,可取状态值的数量应当是有限的。因此在一套状态机图中,应当画出所有的状态取值。

不应当采取走一步看一步的画法,而应当在制图前首先考虑状态可能取值的数量,确定后再进行绘图。绘图完成后应当进行数量上的校验。

当然,不排除前期思考存在疏漏的可能,也不排除冗余的可能,可以在绘图过程中进行修订调整,但是思考的路线应当秉持正确的顺序。

(3) 应当有唯一的初始状态,可以有终止状态也可以没有

讨论对象的状态,主要的目的是讨论对象当前在哪个状态值上,发生什么事,之后转移到哪个状态值上。如果由此追溯,那么上一个所取得状态值是什么、在上一个是什么这样一路溯源,那么考虑到前文所述的有限时间的要求,在最初的时刻的状态值是什么是必须要进行回答的。这种情况下,必须指定一个初始的状态取值才能够开展下面的工作。因此,绘制状态图时必须指定一个初始状态。

此外一个对象的被考察的状态在同一时刻不能够同时具有两个不同的值,状态取值之间应当是相互排斥的。因此一个对象的初始状态必须是唯一的。

考虑到有限时间的问题,那么对象状态必然也会在最终时刻达到一个最终的值。这个所谓的最终时刻并非人为指定的某个时间点,而是对象的状态进入到一个值,此后就不再发生变化了。这种情形即可认为达到了最终状态。一个对象可能在不同的情况下达到不同的最终状态,因此最终状态可能存在多个。

如果稍微做一点点推广,考虑这样的对象,它的状态不会到达某个永远不再变化的最终状态,而是在状态图中永远不停的变化着。这种情况也是可以进行描述的。此时状态机将不存在终态,这种情况下状态机将永远不停机的运转下去。

当然,对于实际中显然会结束的过程,最终状态是必须的。永不停机的过程在日常生活中实际上是不存在的,因此更多的过程中终态是必不可少的。

画法

例图

可停机与不可停机的状态图画法以及初始、终止状态画法

(4) 孤立的状态不应当存在,所有状态应可以到达、可以停机

有了初始状态和最终状态,那么对于状态机中的每一个状态取值就有了进一步的要求。

一个状态机具备可遍历性,是指一个状态机中的每个状态取值,都存在一条从初始状态转移过来的流转通路。即每一个状态值都应当在某种情况下自初始状态变化过来。如果某个状态值不满足这个要求,那么目标对象将永远不可能处于这个状态。这种情况下要么是不必要的状态,要么是图画错了。

一个状态机具备可停机性,是指一个状态机中的每个状态取值,都存在一条道路能够流转到最终状态去。否则一旦对象处于了这个不能流转到最终状态的状态取值上之后,便再也不能够到达最终状态了。对于明显可停机的过程,这是错误的。

注意

错误例图

图中两个突出状态一个是不可达的,一个是不可止的,均为错误画法

(5) 应当区别于流程图,讨论要点是对象的状态如何变化,而非如何执行某种程序

流程图着重点在于描述一个持续进行的过程自始至终是如何进行的。而状态图描述一个目标对象的状态之间是如何相互转化的。在一些过程的描述方面,流程图和状态图具有相近的描述能力,可以换用。但是应当注意状态图和流程的不同之处,在实际的运用中正确选用。

两者区别的最大之处在于描述问题的切入点间的差异:

状态图讨论对象状态的演变,流程图讨论程序过程的推进。

基于这样的切入点之间的差异,两者之间最为显著的特征就是节点上的标注名称的区别。对于流程图,节点一般采用动词标注,用以表示程序设定的动作。而状态图中的节点表达的是对象的状态取值,应当采用名词形容词副词进行命名。

在实际的建模中,有一类场景会比较特殊。这类场景所描述的是一个业务过程的开展。业务过程是一个活动性的事物,其本身便是使用动词进行命名的。此类过程的各个环节是整体活动的一部分,往往也需要使用动词进行命名。针对这类活动性的事物,采用状态机进行建模时,似乎会打破前述的命名约定,需要仔细处理。

操作中,为了突出状态机是针对这种活动过程本身进行建模,首先应将这个过程整体作为一个名词所描绘的事物来处理。一般的策略是将这类过程命名为事务。例如公文审批过程,可以称为公文审批事务。

这样中心词从动词审批,转换为名词事务。在本质上实现了名词化。之后,对于事务中的各个环节,不得不采用动词描述的,应当添加“前”、“中”、“后”、“未”、“已~”等前后词缀,进行副词化。这样便可进行状态图建模了。

例图

公文审批事务一例,其中审批、废弃两个环节本身为动词,使用副词化方法将其转为适当名称后使用

在实际的运用中,也有直接使用动词本身作为状态节点标注的,这时应视为“~中”形式的简化。但这种方式是不规范的,应当避免。

模型校验法

在本节的最后,简要的概括一下状态机建模完成后的校验方法。

一个状态机模型,首先应当进行的校验是基本的拓扑结构校验,即前文提到:

拓扑结构校验

其次应进行语义校验,主要检查

语义校验

最后进行模型完备性校验

完备性校验

模型的完备性校验并非机械性校验,因建模过程中可能存在缩并、拆分、废弃、增加等调整,只能在一定程度上对模型的正确新提供引导。

上述拓扑结构校验和语义校验是检验状态机建模的必要环节,若校验不通过则模型中必然存在错误,但校验通过并不代表模型一定不存在错误。正确的建模技能更多的是建立与长期不懈的学习与训练的基础上的。

三、常见结构提要

状态机作图中,常见的几种基本结构是有必要掌握的。

1. 条件结构

状态机建模本身通过条件性流转提供了条件选择结构,这是一种自然的内嵌结构。例如前文公文审批例图中的“审批中”分“通过”、“否决”而流向不同的流入态。

实际上,状态机本身的条件流转特征在数学上是完备的,任何一种需要的非并发过程均可由具有条件流转的状态机进行模拟。

2. 循环结构

将条件结构适当调整一下,使其中一条流转流向当前状态节点的前级状态节点,形成一个环路,既可构造循环结构。前文公文审批例图中的“决案”状态的“重新修订”流转便是这样的情况。更一般的形式如下图例。

例图

循环结构,当然这只是其中一种循环形式,只要能够构造出环路结构便可构成循环

3. 伺服结构

在实际应用中,有一类特殊的情况相对比较常见。对象相对较长久的出于一个特定中心状态,仅当某些触发性条件发生时,会较为迅速的在某个状态链条中进行跃变,之后又会回到前述特定状态。若具有多个不同快速跃变的状态链条,这样就形成了伺服结构,这个特定的中心状态称为伺服态。

例如收发室老大爷的工作状态在一定简化程度上既可视为具有伺服结构。

例图

收发室老大爷的伺服工作状态

此类伺服结构在窗口服务类以及引申的服务情境下是非常常见的。

四、结语

至此,状态机建模方法与状态机建模过程基本技法的介绍即告一段落。读者能够准确的运用状态机在各种工作场景中开展高效、准确的建模,单单依靠本篇文章的介绍是远远不够的。而且本篇文章立足于基础,对于状态机模型中的并发性问题、信号传递问题、协同问题都没有进行涉足,若希望有进一步了解,可以参阅UML2.0以及其他相关的扩展阅读内容。

业精于勤荒于嬉,在学习状态机建模技术,作者对此是深有体会的,不经期年累月的学习,在概念理解若不得到彻底的提升,是难于掌握这个技术方法的。也望众多读者加油、共勉。

扩展阅读

wikipedia 总是不错的入口

上一篇下一篇

猜你喜欢

热点阅读