什么是状态机
状态机也叫有限状态机(FSM),是一个计算的数学模型。
状态个数有限,在一个时刻,系统处于一种状态。收到触发事件之后,系统可能会做出动作或者转移状态。
状态机核心元素:
现态:是指当前所处的状态。
条件:又称为事件。当一个条件被满足,可能将会触发一个动作,或者执行一次状态的迁移。
动作:条件满足后执行的动作行为。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。
状态机特征:
- 状态总数(state)是有限的。
- 任一时刻,只处在一种状态之中。
- 某种条件下,会从一种状态转变(transition)到另一种状态。
状态机可以对状态增加进入动作(entry action)或退出动作(exit action)
常见表方式
方式一:
事件 | 当前状态 | 次状态 | 动作 |
---|---|---|---|
E1 | S1 | Si | Ax |
E2 | S1 | Sj | Ay |
... | ... | ... | ... |
En | S1 | Sk | Az |
E1 | S2 | Si' | Ax' |
E2 | S2 | Sj' | Ay' |
... | ... | ... | ... |
En | S2 | Sk' | Az' |
... | ... | ... | ... |
E1 | Sm | Si'' | Ax'' |
E2 | Sm | Sj'' | Ay'' |
... | ... | ... | ... |
En | Sm | Sk'' | Az'' |
方式二:
E1 | E2 | ... | En | |
---|---|---|---|---|
S1 | Sj/Ax | Sj/Ay | ... | Sk/Az |
S2 | Si'/Ax' | Sj'/Ay' | ... | Sk'/Az' |
... | ... | ... | ... | |
Sm | Si''/Ax'' | Sj''/Ay'' | ... | Sk''/Az'' |
方式三:
S1 | S2 | ... | Sm | |
---|---|---|---|---|
S1 | Ei/Ax | - | ... | - |
S2 | - | - | ... | Ej/Ay |
... | ... | ... | ... | ... |
Sm | - | Ek/Az | ... | - |
UML状态机
为了解决状态机的状态爆炸(state and transition explosion)问题,UML对传统状态机进行了扩展。
UML状态机相对于传统状态机的最重要创新是引入了层次嵌套状态,以此UML状态机也叫层次状态机(HSM)。
实质就是消除重复。
比如传统状态机可能出现在不同状态下,相同事件下,动作是一样的。类似面向对象中的继承,相同的动作可以被抽象到父状态(superstate)。
如上图的传统状态机中,计算器可以从任何状态跳转到OFF状态,也就是说都要执行相同的状态转移动作。
而在层次状态机中,定义一个新状态ON,operand1,operand2,opEntered和result状态都是ON的子状态(substate)。当用户按下OFF键的时候,子状态发现不能处理,就把事件给到父状态去处理。
状态转移
在UML状态机中执行状态转移规则如下:
- 执行guard运算,如果为true继续下面步骤
- 执行退出动作
- 执行转移关联动作
- 执行进入动作
如:S11 转移到T111
执行顺序为:xS11 -> t1 -> xS1 -> t2 -> eT1 -> eT11 -> t3 -> eT111
事件延迟处理
一个状态可以指定一组可以在该状态中推迟的事件类型。 这意味着那些事件的发生只要该状态仍处于活动状态,就不会调度这些类型。传统状态机对于当前状态不能处理事件往往丢弃。在层次状态机中,事件可以被父状态处理,但是都不能处理的时候也会选择丢弃。通过增加事件延迟处理功能,加强了事件处理的灵活性。
REF
https://www.jianshu.com/p/20d7f7c37b03
https://www.jianshu.com/p/3bd1db91a4bf
https://en.wikipedia.org/wiki/UML_state_machine#Hierarchically_nested_states