robot
最新文章(10)
Mqskit 和其它相關工具
CPython 的 GC 二、三事
寫 Mecurial Extension 是件快樂的事!
Mozilla 台灣辨公室徵人啟事
關於 Apple 的兩項專利
core dump 之前的 frame
怎麼發出 beep 聲?
先承認你要找的是奴才吧!
程式碼要清的多乾淨?
FreeBSD 的 Thread-Local Storage 實作
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (122)
Python (93)
FreeBSD (71)
WEB (61)
URL (48)
hardware (46)
javascript (36)
Linux (34)
blog (30)
C++ (16)
所有關鍵字
新增 URL
這次不用 State Pattern
by thinker
2 Columns
關鍵字:
coding
C++
此處以 $C++$ 為例,起因於寫某支程式時,剛好遇到一個常見的狀態問題。事出於我有一個 class ,必需依照 instance 本身的狀態運作。對於熟悉 $design patterns$ 的人,可能會建議我用 state pattern 。但我不想這麼做,一來程式會因此變的更長更複雜,二來程式邏輯被分散了。這對小小的一段程式而言,實在弊大於利。 {{{#!cpp class foo { int enabled; int in_act1; char *act2_buf; public: void action1_start(void); void action1_stop(void); void action2_start(void); void action2_stop(void); ....... }; }}} 以上例為例, foo 提供兩項功能,用來啟動和停止兩個流程, action1 和 action2 。這兩個流程式互斥的,同一時間只能有其中之一在進行。 action2 在運作時,會將 act_buf 指向一個 string ,結束時將之 reset 成 NULL 。另外我們有 in_act1 ,用以記錄 action1 是否正在運作中。另外,我們有一個 enabled 變數,只有在 enabled 這個變數為 true 時, action1 和 action2 才能運作。於是程式可能就像這樣: {{{#!cpp void foo::action1_start(void) { assert(enabled && !in_act1 && !act2_buf); ...... in_act1 = 1; } void foo::action1_stop(void) { assert(enabled && in_act1); ..... in_act1 = 0; } }}} 像這種情況, state 是透過數個判斷所構成的,也就是多重狀態。這時, assert 會變的很複雜,若是 action1 和 action2 又提供其它的 method 用以互動,那複雜的判斷邏輯更是散的滿地。這時,不斷重複出現的邏輯判斷,很容易造成錯誤。可能是手誤、打錯,或者一時疏忽,總之重複越多次,錯誤的機會越大。這時可以 refactory to function ,將邏輯判斷編寫成一個 inline function 。 {{{#!cpp class foo { .... int is_standby(void) { return enabled && !in_act1 && !act2_buf; } int is_act1_ing(void) { return enabled && in_act1; } int is_act2_ing(void) { return enabled && act2_buf; } ..... }; void foo::action1_start(void) { assert(is_standby()); ...... in_act1 = 1; } void foo::action1_stop(void) { assert(is_act1_ing()); ..... in_act1 = 0; } }}} 如此可以避免重複輸入這些邏輯的錯誤,也能進一步的說明該邏輯的義意。這樣的做法至少有三個作用: # 清楚的說明該邏輯的意函 # 幫助寫作者更明確的釐清該 conditon 的目的,寫出正確的邏輯式。 # 閱讀時,更加直覺和順暢,思絮不會因為分析邏輯式而中斷。 如果你的程式實在複雜,功能眾多,也許 state pattern 才是較好的選擇。但對於小 class 而言,這種方式更勝於 state pattern 。
最後更新時間: 2007-02-28 00:25:06 CST |
引用
查詢:
COMMENTS: