微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > State状态模式推导过程以及完整实现

State状态模式推导过程以及完整实现

时间:09-17 来源:周立功单片机 点击:

近日周立功教授公开了数年的心血之作《程序设计与数据结构》,电子版已无偿性分享到电子工程师与高校群体下载,经周立功教授授权,特对本书内容进行连载。

>>> 1.1.1 动作类

前面详细介绍了State状态模式的推导过程以及完整的实现,采用了简单的打印语句作为作为4个动作的实现示例。然而,实际动作是很有可能发生变化的,由于动作直接在事件处理方法中执行。比如,LOCKED状态的card事件处理方法定义为:

1    void locked_card(turnstile_t *p_turnstile) 

2    { 

3         turnstile_state_set(p_turnstile, &unlocked_state); 

4             printf("unclock\n");                                 // 执行unlock动作

5    }

由此可见,只要动作发生变化,都必须修改事件处理方法。基于此,不妨将闸机动作单独封装在一个动作类中,详见图 4.12。

图 4.12 状态机类图

如程序清单4.23和程序清单4.24所示为动作类的声明和实现,为何要为这么简单的动作创建类呢?因为只有预测变换和管理变化才能拥抱变化,只有这样才能使软件具有可扩展性和可维护性。

程序清单4.23动作函数声明(turnstile_action.h文件内容)

1    #pragma once

2

3    void turnstile_action_lock(void);

4    void turnstile_action_unlock(void); 

5    void turnstile_action_alarm(void); 

6    void turnstile_action_thankyou(void);

程序清单4.24动作函数实现(turnstile_action.c文件内容)

1    void turnstile_action_lock(void) 

2    { 

3         printf("clock\n"); 

4    } 

5

6    void turnstile_action_unlock(void) 

7    { 

8         printf("unclock\n"); 

9    } 

10

11  void turnstile_action_alarm(void)

12  { 

13        printf("alarm\n"); 

14  } 

15

16  void turnstile_action_thankyou(void) 

17  {

18        printf("thank you\n"); 

19  }

程序中的alarm、unlock、thankyou和lock动作对应的动作函数分别为: alarm()、unlock()、thankyou()和lock()。当将4个动作分别由4个函数实现时,则具体动作从状态机中分离出来了。比如,LOCKED状态下的card事件处理方法定义为:

1    void locked_card(turnstile_t *p_turnstile)

2   { 

3         turnstile_state_set(p_turnstile, &unlocked_state); 

4             turnstile_action_unlock ();                             // 执行unlock动作 

5    } 

这是一种良好的设计,因为动作接口优雅地解除了FSM的状态变换逻辑和它要执行的动作之间的耦合。这样一来就算另外一个具有完全不同逻辑的FSM,也可以在没有任何影响的情况下使用这些动作接口。

由于在处理动作时,不需要任何数据,它是一个只有方法,没有属性的动作类,因此没有刻意使用结构体为其定义专门的类型。而实际的动作类可能会包含一些数据,其定义如下:

typedef struct _turnstile_action { 

           // some data

} turnstile_action_t;

此时,当动作发生变化时,仅需修改动作类的函数

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top