什么是状态机?
有限状态机,英文翻译是 Finite State Machine,缩写为 FSM,简称为状态机。状态机有 3 个组成部分:状态(State)、事件(Event)、动作(Action)。其中,事件也称为转移条件(Transition Condition)。事件触发状态的转移及动作的执行。不过,动作不是必须的,也可能只转移状态,不执行任何动作。
实现状态机的方法有多种,比较常用的有分支逻辑法、查表法、状态模式。
我们以一个简单的 CD 播放器为例子。这个例子里面只有状态、事件,不包含动作
按键 | 功能 |
[Play/Pause] | 播放/暂停 |
[Stop] | 停止 |
状态迁移图:
状态机实现方式一:分支逻辑法
它的核心思想是根据状态迁移图,要么先确定状态、要么先确定事件,直译代码。
方法分析:对于简单状态机,该法是可以接受的。但是,对于复杂的状态机,这种实现极易漏写或错写某个状态转移;代码中充斥大量if-else或switch-case 分支判断逻辑,可读性和可维护性差。
如下就是先确定事件,然后再在事件内根据状态进行状态转移。
1 typedef enum { 2 ST_IDLE, 3 ST_PLAY, 4 ST_PAUSE 5 } State; 6 7 typedef enum { 8 EV_PLAY_PAUSE, 9 EV_STOP 10 } Event; 11 12 State state; 13 14 // 初始化 15 void initialize() { 16 state = ST_IDLE; 17 } 18 19 // play or pause 20 void playOrPause() { 21 if (state == ST_IDLE) { 22 state = ST_PLAY; 23 } else if (state == ST_PLAY) { 24 state = ST_PAUSE; 25 } else if (state == ST_PAUSE) { 26 state = ST_PLAY; 27 } 28 } 29 30 // stop 31 void stop() { 32 if (state == ST_PLAY || state == ST_PAUSE) { 33 state = ST_IDLE; 34 } 35 } 36 37 // 事件响应 38 void onEvent(Event ev) { 39 switch (ev) { 40 case EV_PLAY_PAUSE: 41 playOrPause(); 42 break; 43 case EV_STOP: 44 stop(); 45 break; 46 default: 47 break; 48 } 49 }
啊啊啊