深入浅出理解有限状态机
有限狀態機是一種用來進行對象行為建模的工具,其作用主要是描述對象在它的生命周期內所經歷的狀態序列,以及如何響應來自外界的各種事件。在計算機科學中,有限狀態機被廣泛用于建模應用行為、硬件電路系統設計、軟件工程,編譯器、網絡協議、和計算與語言的研究。比如下圖非常有名的TCP協議狀態機。
其實我們在編程時實現相關業務邏輯時經常需要處理各種事件和狀態切換,寫各種switch/case 和if/else ,所以我們其實可能一直都在跟有限狀態機打交道,只是可能沒有意識到。在處理一些業務邏輯比較復雜的需求時,可以先看看是否適合用一個有限狀態機來描述,如果可以把業務模型抽象成一個有限狀態機,那么代碼就會邏輯特別清晰,結構特別規整。
下面我們就來聊聊所謂的狀態機,以及它如何在代碼中實現。
1、狀態機的要素
狀態機可歸納為4個要素,即現態、條件、動作、次態。“現態”和“條件”是因,“動作”和“次態”是果。詳解如下:
①現態:是指當前所處的狀態。
②條件:又稱為“事件”。當一個條件被滿足,將會觸發一個動作,或者執行一次狀態的遷移。
③動作:條件滿足后執行的動作。動作執行完畢后,可以遷移到新的狀態,也可以仍舊保持原狀態。動作不是必需的,當條件滿足后,也可以不執行任何動作,直接遷移到新狀態。
④次態:條件滿足后要遷往的新狀態。“次態”是相對于“現態”而言的,“次態”一旦被激活,就轉變成新的“現態”了。
我們可以用狀態表了表示整個過程,如下圖所示。
狀態表這里需要注意的兩個問題:
1、避免把某個“程序動作”當作是一種“狀態”來處理。那么如何區分“動作”和“狀態”?“動作”是不穩定的,即使沒有條件的觸發,“動作”一旦執行完畢就結束了;而“狀態”是相對穩定的,如果沒有外部條件的觸發,一個狀態會一直持續下去。
2、狀態劃分時漏掉一些狀態,導致跳轉邏輯不完整。
所以維護上述一張狀態表就非常必要,而且有意義了。從表中可以直觀看出那些狀態直接存在跳轉路徑,那些狀態直接不存在。如果不存在,就把對應的單元格置灰。 每次寫代碼之前先把表格填寫好,并且對置灰的部分重點review,看看是否有“漏態”,然后才是寫代碼。QA拿到這張表格之后,寫測試用例也是手到擒來。
2、狀態機在object-C的代碼實現。
我在開發百度地圖導航過程頁以及百度CarLife的反控手機識別中都用到了有些狀態機編程,下面我結合個人的經驗,給大家分享一個iOS程序中實現有限狀態機的寫法。
先回顧一下上面那個狀態表,其中狀態變遷時執行的動作,可能是由一系列的元動作組成,并且通常都是跟現態和次態強相關的,所以,我把狀態表做一個改進,如下所示:
其中:FSM_FUN(stateA,stateB) 就表示,從狀態stateA跳轉到stateB時要執行的所有元動作的有序集。
1、準備工作,狀態定義和事件定義
宏定義這里沒有啥特殊的,主要是借助宏定義,比較巧妙的實現枚舉值到字符串的轉換,比如枚舉值stateA,能自動生成字符串@“stateA”,用于后面的狀態函數名拼接。這是一個通用的枚舉值自動轉字符串的解決方案,參考的鏈接( http://stackoverflow.com/a/202511)
2、Model類定義
iOS開發都會采用MVC架構或者相關變種,但是狀態的維護都會實現在Model中。這里定義了一個簡單的TestModel,它有一個成員變量state,保存著當前的狀態。
Model定義3、實現Model類的一個category,
里面主要定義和實現了狀態跳轉時要執行的一些動作。
4、重新Model的setState方法,使得在設置狀態時能自動去執行狀態跳轉時需要執行的動作。
5、處理事件輸入,實現狀態跳轉邏輯。
這里有兩種寫法,一種是在狀態中判斷事件:
狀態中判斷事件一種是事件中判斷狀態:
事件中判斷狀態思考與討論:
狀態跳轉邏輯的兩種寫法,實現的功能和效果完全相同,孰優孰劣,歡迎留言探討。
本人觀點:一般業務場景來說,狀態的數量是確定的切數目較少,不同狀態下需要處理的事件也不一樣。而觸發的事件數量則比較多,采用上面第二種方式在事件中判斷狀態也有利于把里面一層的switch/case剝離出來當成單獨的函數,做一些代碼模塊結構的優化,故推薦使用第二種方式,事件中判斷狀態。
優化后的狀態變化函數代碼,如下圖。
優化后歡迎探討
本文主要介紹了一下什么是有限狀態機,然后通過一個具體的代碼示例介紹了一些本人在狀態機編程上的經驗和理解,歡迎各位進行交流指正。
謝謝大家的寶貴時間。
作者:我是云峰小羅 鏈接:http://www.jianshu.com/p/5eb45c64f3e3 來源:簡書 著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。總結
以上是生活随笔為你收集整理的深入浅出理解有限状态机的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于有限自动机的一篇不错的文章
- 下一篇: 状态机思路在程序设计中的应用