近日周立功教授公開了數年的心血之作《程序設計與數據結構》,電子版已無償性分享到電子工程師與高校群體下載,經周立功教授授權,特對本書內容進行連載。
>>>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;
此時,當動作發生變化時,僅需修改動作類的函數,無需修改狀態機的事件處理函數。
-
電子工程師
+關注
關注
252文章
768瀏覽量
95645 -
嵌入式
+關注
關注
5086文章
19140瀏覽量
305882 -
周立功
+關注
關注
38文章
130瀏覽量
37664
原文標題:周立功:狀態機——動作類
文章出處:【微信號:Zlgmcu7890,微信公眾號:周立功單片機】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論