看过类似的文章,加上自己的理解,记录一下。
假设状态机的状态转换由下表所示:
当前状态 | State0 | State1 | State2 | 事件 |
action0/state1 | action1/state2 | action3/state0 | event0 | |
action4/state1 | event1 | |||
action5/state2 | action6/state0 | event2 |
简单讲一下状态转换过程:当处于State0时发生event0 则执行action0并将状态变成state1,当state1状态下发生event2则执行action6并将状态变成state2。以此类推。
下面描述下实现上述状态机的两种不同的写法:
1)竖着写:在状态中判断事件,并执行相应的操作,完成相应的状态转换。
2)横着写:在事件中根据当前的状态,执行相应的操作,完成相应的状态转换。
两种写法的实现C代码:
//竖着写
switch(cur_state)
{
case State0:
if(event1)
{
action0;
cur_state = State1;
}
else if(event2)
{
action4;
cur_state = State1;
}
else if(event3)
{
action5;
cur_state = State2;
}
break;
case State1:
if(event1)
{
action1;
cur_state = State2;
}
else if(event3)
{
action6;
cur_state = State0;
}
break;
case State2:
if(event1)
{
action3;
cur_state = State0;
}
break;
default:break;
}
//横着写
void event0func(void)
{
switch(cur_state)
{
case State0:
action0;
cur_state = State1;
break;
case State1:
action1;
cur_state = State2;
break;
case State2:
action1;
cur_state = State0;
break;
default:break;
}
}
void event1func(void)
{
switch(cur_state)
{
case State0:
action4;
cur_state = State1;
break;
default:break;
}
}
void event2func(void)
{
switch(cur_state)
{
case State0:
action5;
cur_state = State2;
break;
case State1:
action6;
cur_state = State0;
break;
default:break;
}
}
上述两种写法实现的功能完全相同,对比两种写法:
1)写法1(竖着写)使用了if -else if语句隐含了优先级,破坏可事件间的原有关系(各个时间应该同优先级)
2)写法1(竖着写)在结构上是顺序查询方式(查询事件),浪费大量的时间,而且时间不可估算。
写法2(横着写)因为在某个时间点上状态是唯一确定的,在时间处理函数中通过switch语句可直接定位到相同状态,
执行时间也可以估算。
3)写法2(横着写)比较直观,程序执行效率较高。
总体来说:写法2要优于写法1。