天天看點

有限狀态機實作-狀态機介紹

這個系列最終實作的狀态機并不是一個标準的狀态機,把狀态機的很多标準的概念進行了簡化,對概念的東西做了減法,實作了具備基本功能的狀态機(很多所謂狀态機更進階的功能,如:僞态,也可以在基本功能實作)。整個狀态機的實作将分為下面幾個章節介紹
  • 狀态機介紹
  • 簡單有限狀态機的實作
  • 簡單有限狀态機的應用執行個體
  • 簡單狀态機功能增強
  • 有限狀态機狀态持久化設計
  • 有限狀态機持久化實作 目前章節以理論為主

有限狀态機概念

有限狀态機簡稱就是狀态機,因為一般的狀态機的狀态都是離散和可舉的,即為有限,是以後面的介紹都不加有限二字。狀态機表示有限個狀态以及在這些狀态之間的轉移和動作等行為的數學模型。通俗的描述狀态機就是定義了一套狀态変更的流程:狀态機包含一個狀态集合,定義當狀态機處于某一個狀态的時候它所能接收的事件以及可執行的行為,執行完成後,狀态機所處的狀态。是以狀态機會包含以下幾個重要的元素:
  • State:狀态。一個标準的狀态機最少包含兩個狀态:初始和終态。初态是狀态機初始化後所處的狀态,而終态顧名思義就是狀态機結束時所處的狀态。其他的狀态都是一些流轉中停留的狀态。标準的狀态機還會涉及到一些中間态,存在中間态的狀态機流程就會比較複雜(用處也不是特别大,而且可以通過其他方式實作),是以在目标實作的狀态機裡不會引入這個概念。
  • Event:事件。還有中描述叫Trigger,表達的意思都一樣,就是要執行某個操作的觸發器或密碼:當狀态機處于某個狀态時,隻有外界告訴狀态機要幹什麼事情的時候,狀态機才會去執行具體的行為,來完成外界想要它完成的操作。比如出去吃飯,說“點菜”,服務員才會拿着小本過來記錄你要吃的菜,說的那句“點菜”,就相當于Event。
  • Action:行為。狀态變更索要執行的具體行為。還是拿上面點菜的例子,服務員拿小本記錄你定的菜的過程就是Action
  • Transition:變更。一個狀态接收一個事件執行了某些行為到達了另外一個狀态的過程就是一個Transition。定義Transition就是在定義狀态機的運轉流程。
有限狀态機實作-狀态機介紹

狀态圖

上圖就是一個最簡單的狀态機,一個初态,一個流轉狀态,一個終态,初态到流狀态是不需要任何操作的,State1當發生了Event1事件時,執行Action1到達了終态。(我們最終實作的狀态機,會把初态和終态都當做一個流狀态來對待)。

說了這麼多,狀态機能幹什麼?狀态機主要的應用場景就是流程控制。一個狀态機定義以後,在某個狀态下就隻接收固定的Event,也就是執行指定的操作,這樣流程就能按照預期定義的那樣流轉,不會出現亂入的情況,執行了一些在某狀态下不允許執行的操作。一個很典型的應用就是工作流引擎:以工作流中典型的審批流程為例,審批流程按照預先定義的流程流轉的固定的某些人手裡,隻有這一批固定的人才能審批,當審批後(可能是一個人審批,也可能是多個人審批)才會流轉到下個節點,由下個節點的審批人繼續審批,一直流轉到最後一個節點。狀态機的流轉可以人工幹預,也可以自動流轉。定義為自動流轉後,把業務流程定義完成後,隻要添加一個定時任務,整個流程的運轉就都由狀态機來完成了。此外,當狀态機加入了持久化操作後,所有的狀态流轉都會落地,當業務出現異常,友善定位問題,當流程定義的足夠細粒度的話,還可以通過驅動狀态機來實作重入,恢複異常的節點。

狀态模式

在實作狀态機之前,我們順便簡單的看一下設計模式中的狀态模式,這個模式跟我們實作狀态機的代碼結構還是有一定的關系的。

狀态模式:封裝基于狀态的行為,并将行為委托到目前的狀态。
           

試想一下,現在有一種業務場景存在多個狀态,比如一個要遭受攻擊的遊戲人物,當人物遭受攻擊後我們要減少人物的血量,而目前人物可能處于的狀态有如下(遊戲中常見的一些場景):剛複活(對一切攻擊免疫),正常狀态,實體攻擊免疫,魔法攻擊免疫,攻擊随機無效,各種疊加态。當攻擊來了,人物該怎麼掉血。在非使用狀态模式的情況下,一種常見的寫法,人物接受攻擊,然後開始各種判斷現在人物所處于的狀态,各種if...else,當新的需求來額時候,就修改這些if...else。而采用狀态模式,行為委托類儲存着目前人物所處的狀态,當攻擊來了,委托類會把該攻擊交由持有的狀态來處理,實作了對修改關閉,對擴充開放。類圖如下(具體就不上代碼了,感興趣的可以自己研究一下):

有限狀态機實作-狀态機介紹

狀态模式

  • Context:可以了解為上下文,它持有目前的狀态,同時對外暴露狀态行為接口
  • State:定義了狀态下的行為接口
  • ConcreteState:行為接口的具體實作

其中Context是一個關鍵,在我們将要實作的狀态機裡扮演者重要的角色。

此外我們将要的實作的狀态機遠遠不是一個狀态模式的一個實作,要比它複雜的多。

目标狀态機功能介紹

  • 狀态機的定義:通過定義State,Event,Action,Transition來實作狀态機的流轉,摒棄标準狀态機中那些較複雜的概念(通過其他方式來實作所謂的較複雜的操作)
  • 狀态持久化:資料持久化到資料庫,實作狀态機的中斷重新開機
  • 上下文儲存與傳遞:提供一套流程流轉過程中參數的傳遞機制
  • 并發控制:提供不同狀态機隔離,同一狀态機單執行個體運作機制
  • 功能增強:接口或注解的形式實作自觸發,重試,定時執行

github上有一開源狀态機,算是github上狀态機系列java得星最多的項目,功能已經做的很強大,本人早期的時候關注過,但是到目前為止已經做的很複雜了,超出了大部分正常的使用場景,而且幾個版本下來,代碼風格也有了很大的變化。感興趣的同學可以先看一下:

https://github.com/hekailiang/squirrel

此外Spring也有一套狀态機,但對spring版本有要求,有生産需求的同學也可以考慮一下

參考文獻:

1.http://www.jianshu.com/p/d48e0d565618

繼續閱讀