有限狀態(tài)機實現(xiàn)-狀態(tài)機介紹

這個系列最終實現(xiàn)的狀態(tài)機并不是一個標準的狀態(tài)機,把狀態(tài)機的很多標準的概念進行了簡化寞钥,對概念的東西做了減法,實現(xiàn)了具備基本功能的狀態(tài)機(很多所謂狀態(tài)機更高級的功能理郑,如:偽態(tài)蹄溉,也可以在基本功能實現(xiàn))您炉。整個狀態(tài)機的實現(xiàn)將分為下面幾個章節(jié)介紹

  • 狀態(tài)機介紹
  • 簡單有限狀態(tài)機的實現(xiàn)
  • 簡單有限狀態(tài)機的應(yīng)用實例
  • 簡單狀態(tài)機功能增強
  • 有限狀態(tài)機狀態(tài)持久化設(shè)計
  • 有限狀態(tài)機持久化實現(xiàn)
    當前章節(jié)以理論為主

有限狀態(tài)機概念

有限狀態(tài)機簡稱就是狀態(tài)機柒爵,因為一般的狀態(tài)機的狀態(tài)都是離散和可舉的,即為有限赚爵,所以后面的介紹都不加有限二字棉胀。狀態(tài)機表示有限個狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動作等行為的數(shù)學模型法瑟。通俗的描述狀態(tài)機就是定義了一套狀態(tài)変更的流程:狀態(tài)機包含一個狀態(tài)集合,定義當狀態(tài)機處于某一個狀態(tài)的時候它所能接收的事件以及可執(zhí)行的行為霎挟,執(zhí)行完成后,狀態(tài)機所處的狀態(tài)氓扛。所以狀態(tài)機會包含以下幾個重要的元素:

  • State:狀態(tài)论笔。一個標準的狀態(tài)機最少包含兩個狀態(tài):初始和終態(tài)。初態(tài)是狀態(tài)機初始化后所處的狀態(tài)最楷,而終態(tài)顧名思義就是狀態(tài)機結(jié)束時所處的狀態(tài)。其他的狀態(tài)都是一些流轉(zhuǎn)中停留的狀態(tài)。標準的狀態(tài)機還會涉及到一些中間態(tài)犯建,存在中間態(tài)的狀態(tài)機流程就會比較復(fù)雜(用處也不是特別大讲冠,而且可以通過其他方式實現(xiàn)),所以在目標實現(xiàn)的狀態(tài)機里不會引入這個概念适瓦。
  • Event:事件竿开。還有中描述叫Trigger,表達的意思都一樣玻熙,就是要執(zhí)行某個操作的觸發(fā)器或口令:當狀態(tài)機處于某個狀態(tài)時否彩,只有外界告訴狀態(tài)機要干什么事情的時候,狀態(tài)機才會去執(zhí)行具體的行為嗦随,來完成外界想要它完成的操作列荔。比如出去吃飯,說“點菜”枚尼,服務(wù)員才會拿著小本過來記錄你要吃的菜肌毅,說的那句“點菜”,就相當于Event姑原。
  • Action:行為悬而。狀態(tài)變更索要執(zhí)行的具體行為。還是拿上面點菜的例子锭汛,服務(wù)員拿小本記錄你定的菜的過程就是Action
  • Transition:變更笨奠。一個狀態(tài)接收一個事件執(zhí)行了某些行為到達了另外一個狀態(tài)的過程就是一個Transition袭蝗。定義Transition就是在定義狀態(tài)機的運轉(zhuǎn)流程。
狀態(tài)圖

上圖就是一個最簡單的狀態(tài)機般婆,一個初態(tài)到腥,一個流轉(zhuǎn)狀態(tài),一個終態(tài)蔚袍,初態(tài)到流狀態(tài)是不需要任何操作的乡范,State1當發(fā)生了Event1事件時,執(zhí)行Action1到達了終態(tài)啤咽。(我們最終實現(xiàn)的狀態(tài)機晋辆,會把初態(tài)和終態(tài)都當做一個流狀態(tài)來對待)。

說了這么多宇整,狀態(tài)機能干什么瓶佳?狀態(tài)機主要的應(yīng)用場景就是流程控制。一個狀態(tài)機定義以后鳞青,在某個狀態(tài)下就只接收固定的Event霸饲,也就是執(zhí)行指定的操作,這樣流程就能按照預(yù)期定義的那樣流轉(zhuǎn)臂拓,不會出現(xiàn)亂入的情況厚脉,執(zhí)行了一些在某狀態(tài)下不允許執(zhí)行的操作。一個很典型的應(yīng)用就是工作流引擎:以工作流中典型的審批流程為例胶惰,審批流程按照預(yù)先定義的流程流轉(zhuǎn)的固定的某些人手里傻工,只有這一批固定的人才能審批,當審批后(可能是一個人審批童番,也可能是多個人審批)才會流轉(zhuǎn)到下個節(jié)點精钮,由下個節(jié)點的審批人繼續(xù)審批威鹿,一直流轉(zhuǎn)到最后一個節(jié)點剃斧。狀態(tài)機的流轉(zhuǎn)可以人工干預(yù),也可以自動流轉(zhuǎn)忽你。定義為自動流轉(zhuǎn)后幼东,把業(yè)務(wù)流程定義完成后,只要添加一個定時任務(wù)科雳,整個流程的運轉(zhuǎn)就都由狀態(tài)機來完成了根蟹。此外,當狀態(tài)機加入了持久化操作后糟秘,所有的狀態(tài)流轉(zhuǎn)都會落地简逮,當業(yè)務(wù)出現(xiàn)異常,方便定位問題尿赚,當流程定義的足夠細粒度的話散庶,還可以通過驅(qū)動狀態(tài)機來實現(xiàn)重入蕉堰,恢復(fù)異常的節(jié)點。

狀態(tài)模式

在實現(xiàn)狀態(tài)機之前悲龟,我們順便簡單的看一下設(shè)計模式中的狀態(tài)模式屋讶,這個模式跟我們實現(xiàn)狀態(tài)機的代碼結(jié)構(gòu)還是有一定的關(guān)系的。

狀態(tài)模式:封裝基于狀態(tài)的行為须教,并將行為委托到當前的狀態(tài)皿渗。

試想一下,現(xiàn)在有一種業(yè)務(wù)場景存在多個狀態(tài)轻腺,比如一個要遭受攻擊的游戲人物乐疆,當人物遭受攻擊后我們要減少人物的血量,而當前人物可能處于的狀態(tài)有如下(游戲中常見的一些場景):剛復(fù)活(對一切攻擊免疫)约计,正常狀態(tài)诀拭,物理攻擊免疫,魔法攻擊免疫煤蚌,攻擊隨機無效耕挨,各種疊加態(tài)。當攻擊來了尉桩,人物該怎么掉血筒占。在非使用狀態(tài)模式的情況下,一種常見的寫法蜘犁,人物接受攻擊翰苫,然后開始各種判斷現(xiàn)在人物所處于的狀態(tài),各種if...else这橙,當新的需求來額時候奏窑,就修改這些if...else。而采用狀態(tài)模式屈扎,行為委托類保存著當前人物所處的狀態(tài)埃唯,當攻擊來了,委托類會把該攻擊交由持有的狀態(tài)來處理鹰晨,實現(xiàn)了對修改關(guān)閉墨叛,對擴展開放。類圖如下(具體就不上代碼了模蜡,感興趣的可以自己研究一下):

狀態(tài)模式
  • Context:可以理解為上下文漠趁,它持有當前的狀態(tài),同時對外暴露狀態(tài)行為接口
  • State:定義了狀態(tài)下的行為接口
  • ConcreteState:行為接口的具體實現(xiàn)

其中Context是一個關(guān)鍵忍疾,在我們將要實現(xiàn)的狀態(tài)機里扮演者重要的角色闯传。
此外我們將要的實現(xiàn)的狀態(tài)機遠遠不是一個狀態(tài)模式的一個實現(xiàn),要比它復(fù)雜的多卤妒。

目標狀態(tài)機功能介紹

  • 狀態(tài)機的定義:通過定義State甥绿,Event叠必,Action,Transition來實現(xiàn)狀態(tài)機的流轉(zhuǎn)妹窖,摒棄標準狀態(tài)機中那些較復(fù)雜的概念(通過其他方式來實現(xiàn)所謂的較復(fù)雜的操作)
  • 狀態(tài)持久化:數(shù)據(jù)持久化到數(shù)據(jù)庫纬朝,實現(xiàn)狀態(tài)機的中斷重啟
  • 上下文保存與傳遞:提供一套流程流轉(zhuǎn)過程中參數(shù)的傳遞機制
  • 并發(fā)控制:提供不同狀態(tài)機隔離,同一狀態(tài)機單實例運行機制
  • 功能增強:接口或注解的形式實現(xiàn)自觸發(fā)骄呼,重試共苛,定時執(zhí)行

github上有一開源狀態(tài)機,算是github上狀態(tài)機系列java得星最多的項目蜓萄,功能已經(jīng)做的很強大隅茎,本人早期的時候關(guān)注過,但是到目前為止已經(jīng)做的很復(fù)雜了嫉沽,超出了大部分常規(guī)的使用場景辟犀,而且?guī)讉€版本下來,代碼風格也有了很大的變化绸硕。感興趣的同學可以先看一下:
https://github.com/hekailiang/squirrel

此外Spring也有一套狀態(tài)機堂竟,但對spring版本有要求,有生產(chǎn)需求的同學也可以考慮一下


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玻佩,一起剝皮案震驚了整個濱河市出嘹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咬崔,老刑警劉巖税稼,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異垮斯,居然都是意外死亡郎仆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門兜蠕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扰肌,“玉大人,你說我怎么就攤上這事牺氨〗瞥埽” “怎么了墩剖?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵猴凹,是天一觀的道長。 經(jīng)常有香客問我岭皂,道長郊霎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任爷绘,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘草穆。我一直安慰自己嗽交,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布臂港。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垂蜗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天解幽,我揣著相機與錄音贴见,去河邊找鬼。 笑死躲株,一個胖子當著我的面吹牛片部,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霜定,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼档悠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了望浩?” 一聲冷哼從身側(cè)響起站粟,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎曾雕,沒想到半個月后奴烙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡剖张,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年切诀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搔弄。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡幅虑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出顾犹,到底是詐尸還是另有隱情倒庵,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布炫刷,位于F島的核電站擎宝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏浑玛。R本人自食惡果不足惜绍申,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧极阅,春花似錦胃碾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奔脐,卻和暖如春儒旬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背帖族。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工栈源, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人竖般。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓甚垦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涣雕。 傳聞我的和親對象是個殘疾皇子艰亮,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 狀態(tài)機是無論科研探索還是科技應(yīng)用方面都非常重要的一種分析工具。幾乎在所有涉及到隨時間演化的問題中挣郭,都可以找到狀態(tài)機...
    Esmool閱讀 4,418評論 0 26
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,108評論 25 707
  • 周檢視第2周(2017年12月3~12月9日) 沒有記錄就沒有發(fā)生—— 健康:1)泡腳7/7天 2)徒步45000...
    圓圓jXY閱讀 157評論 0 0
  • 今天早上看見黃老師發(fā)的早晨三件事的分享迄埃,具體如下:什么是真朋友?有一個簡單粗暴的標準:能開誠公布地談錢的兑障。朋...
    趙小杰呀閱讀 301評論 2 0
  • DOM:文檔對象模型侄非,以節(jié)點樹的方式描繪HTML或XML文檔 DOM0:未正式成為公認標準前的DOM DOM1:W...
    pingink閱讀 1,662評論 0 0