2011-02-16 25 views
19

是否可以通過應用狀態機模式來改進所有代碼?有限狀態機模式 - 唯一真實模式?

我當時正在研究一個可怕的,越野車,破碎的意大利麪代碼。 我抄錄了Martin Fowler's example State Machine code from this blog,並將整個垃圾堆變成了一系列的陳述。從字面上看,只是一個州,事件,轉換和命令的列表。

我不敢相信這個轉變。代碼現在是乾淨的,並且可以工作。當然,我之前已經知道了狀態機,甚至已經實現了它們,但是在Martin Fowler的例子中,模型/配置的分離是驚人的。

這讓我覺得,我做過的幾乎所有事情都可以從這種方法中獲益。我希望使用每種語言的這種功能。 也許這應該是一個語言級別的功能。

任何人都認爲這是錯的? 或者任何人有不同的模式有類似的經驗?

+1

我喜歡狀態機,很多嵌入式編程問題..我發現當特殊情況,需求發生變化時,模式往往會發生爆炸(狀態的巨大增加)或崩潰(違反模式的人)。進入圖片,特別是當經驗較少/有能力的開發人員進行更改時。某些情況(例如動態指定的重試次數)需要小心在FSM中正確實施。 – Splat 2011-02-20 17:19:13

+0

提防金錘反模式! http://sourcemaking.com/antipatterns/golden-hammer – swinefeaster 2012-11-05 21:53:48

回答

9

通過用專用語言描述解決方案,有限狀態機(FSM)和更具體的領域特定語言(DSL)可以更容易地將問題與一個特定解決方案域相匹配。

狀態機模式的侷限性在於它本身構成了一種編程語言,但您必須編寫自己的執行,測試和調試工具;以及任何維護人員必須學習的東西。您已將代碼的複雜性移至複雜的FSM配置中。偶爾,這是有用的,但肯定不是普遍的。

而且由於任何馮·諾伊曼計算機本身就是一個密克羅尼西亞聯邦,那麼當然任何程序可以重塑這種方式。

+1

我想我將不得不閱讀福勒書。我從來沒有想過將狀態機看作DSL。我看到它是如何改變其他地方的複雜性,但對我來說,這是獎金。它是由看似無關的代碼(在我的情況下,例如媒體播放器,會計應用程序和社交網站)分解爲可重用,經過測試的代碼的核心。謝謝 – hooleyhoop 2011-02-17 15:53:06

8

意大利麪條代碼永遠不是正確的答案。模式善於清理意大利麪條代碼,但只要有一個深思熟慮的設計可以達到同樣的效果。

關於狀態機問題:我個人認爲它們非常有用。對於我創建的一個面向公衆的應用程序,我重構了使用狀態圖(我認爲它與狀態機相同),並注意到您提到的好處。這是一個非常有用的抽象,因爲它允許您將處理事件的注意力分散到單獨的組件中。有了這個,錯誤消失了,因爲狀態圖隱式知道用戶可以在哪裏做什麼,並且由於事件只能在正確的位置處理,所以您無法真正執行無效操作。此外,使用狀態圖允許我簡化代碼,因爲我可以將所有的事件處理代碼放在原來的位置,並將它放在應該在的位置 - 換句話說,其他組件不是他們也沒有事件處理者的複雜性。

一張圖片勝過一千個作品 - 這裏是我想出了設計: enter image description here

有了這個,誰看就知道正是應用程序如何運行在一個較高的水平。很難打破這一點,因爲正如我所說的,你無法進入無效的狀態,因爲事件處理程序確切地控制着你可以去的地方;如果你可以進入一個無效的狀態,它的一個很容易修復的實現錯誤。此外,代碼清理的好處是巨大的。例如,使用狀態圖,每當我輸入任何暫停狀態時,我都可以執行諸如停止時鐘,在板上放置掩碼等。其在的幾行代碼之一 - 因爲當我進入暫停的子狀態,圖表首先通過父狀態。如果沒有狀態圖,我將不得不在處理事件的任何地方執行該代碼。

我不知道它是否需要是語言級別的功能,但有一個良好實施的框架是不錯的。