整理:状态机的两种写法对比

    状态机可以用两种方法实现:竖着写(在状态中判断事件)和横着写(在事件中判断状态)。这两种实现在本质上是完全等效的,但在实际操作中,效果却截然不同。

==================================

竖着写(在状态中判断事件)   C代码片段

==================================

    cur_state = nxt_state;

    switch(cur_state)

    {                  //在当前状态中判断事件

        case s0:       //s0状态

            if(e0_event)

              //如果发生e0事件,那么就执行a0动作,并保持状态不变;

                执行a0动作;

                //nxt_state = s0;       //因为状态号是自身,所以可以删除此句,以提高运行速度。

            }

            else if(e1_event)

              //如果发生e1事件,那么就执行a1动作,并将状态转移到s1态;

                执行a1动作;

                nxt_state = s1;

            }

            else if(e2_event)

            {  //如果发生e2事件,那么就执行a2动作,并将状态转移到s2态;

                执行a2动作;

                nxt_state = s2;

            }

            break;

        case s1:         //s1状态

            if(e2_event)

             {  //如果发生e2事件,那么就执行a2动作,并将状态转移到s2态;

                执行a2动作;

                nxt_state = s2;

            }

            break;

        case s2:         //s2状态

            if(e0_event)

           {   //如果发生e0事件,那么就执行a0动作,并将状态转移到s0态;

                执行a0动作;

                nxt_state = s0;

            }

    }

 

 

==================================

横着写(在事件中判断状态)   C代码片段

==================================

//e0事件发生时,执行的函数

void e0_event_function(int * nxt_state)

{

    int cur_state;

    cur_state = *nxt_state;

    switch(cur_state)

   {

        case s0:                 

        case s2:

            执行a0动作;

            *nxt_state = s0;

    }

}

 

//e1事件发生时,执行的函数

void e1_event_function(int * nxt_state)

{

    int cur_state;

    cur_state = *nxt_state;

    switch(cur_state)

    {

        case s0:                     

            执行a1动作;

            *nxt_state = s1;

    }

}

 

//e2事件发生时,执行的函数

void e2_event_function(int * nxt_state)

{

    int cur_state;    

    cur_state = *nxt_state;

    switch(cur_state)

    {

        case s0:                      

        case s1:

            执行a2动作;

            *nxt_state = s2;

    }

}

 

    上面横竖两种写法的代码片段,实现的功能完全相同,但是,横着写的效果明显好于竖着写的效果。理由如下:

    1、竖着写隐含了优先级排序(其实各个事件是同优先级的),排在前面的事件判断将毫无疑问地优先于排在后面的事件判断。这种if/else if写法上的限制将破坏事件间原有的关系。而横着写不存在此问题。

    2、由于处在每个状态时的事件数目不一致,而且事件发生的时间是随机的,无法预先确定,导致竖着写沦落为顺序查询方式,结构上的缺陷使得大量时间被浪费。对于横着写,在某个时间点,状态是唯一确定的,在事件里查找状态只要使用switch语句,就能一步定位到相应的状态,延迟时间可以预先准确估算。而且在事件发生时,调用事件函数,在函数里查找唯一确定的状态,并根据其执行动作和状态转移的思路清晰简洁,效率高,富有美感。

    总之,我个人认为,在软件里写状态机,使用横着写的方法比较妥帖。

    竖着写的方法也不是完全不能使用,在一些小项目里,逻辑不太复杂,功能精简,同时为了节约内存耗费,竖着写的方法也不失为一种合适的选择。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值