狀態(tài)機(jī)
狀態(tài)機(jī)定義
狀態(tài)機(jī)待德,F(xiàn)inite state machine,簡(jiǎn)稱FSM枫夺。指一個(gè)對(duì)象在有限個(gè)狀態(tài)內(nèi)轉(zhuǎn)移并處理外部事件的數(shù)字模型。
如圖所示绘闷,一個(gè)對(duì)象有n個(gè)狀態(tài)橡庞。假設(shè)初始狀態(tài)為State1较坛,當(dāng)外部事件到來時(shí),處在狀態(tài)State1的對(duì)象處理這個(gè)狀態(tài)并轉(zhuǎn)移到狀態(tài)State2扒最,而這個(gè)對(duì)象在狀態(tài)State2時(shí)接收到外部事件時(shí)又會(huì)處理這個(gè)事件并轉(zhuǎn)移到另外一個(gè)狀態(tài)丑勤。
比如,我們通話的聲道會(huì)有揚(yáng)聲器吧趣、耳機(jī)法竞、聽筒、藍(lán)牙4個(gè)狀態(tài)强挫。假設(shè)我們這通通話的聲道初始狀態(tài)為聽筒岔霸,當(dāng)用戶在通話界面把聲道切為揚(yáng)聲器時(shí),聽筒這個(gè)狀態(tài)會(huì)打開揚(yáng)聲器并轉(zhuǎn)移到揚(yáng)聲器狀態(tài)俯渤。打開揚(yáng)聲器這個(gè)動(dòng)作呆细,我們可以在聽筒狀態(tài)轉(zhuǎn)移到揚(yáng)聲器之前處理,也可以在進(jìn)入揚(yáng)聲器狀態(tài)時(shí)處理八匠。因此絮爷,我們可以有一個(gè)擴(kuò)展的狀態(tài)機(jī)定義:
這個(gè)狀態(tài)機(jī)比上面的狀態(tài)機(jī)每個(gè)State多了enter和exit兩個(gè)action,表示在進(jìn)入或者退出某個(gè)狀態(tài)時(shí)會(huì)做的動(dòng)作梨树,比如上面那個(gè)例子中揚(yáng)聲器State的enter action可以打開揚(yáng)聲器而其exit action可以關(guān)閉揚(yáng)聲器坑夯。如圖所示:
分層狀態(tài)機(jī)
分層狀態(tài)機(jī),Hierarchical Finite State Machine抡四,簡(jiǎn)稱HFSM柜蜈。即對(duì)象的N個(gè)有限狀態(tài)中的某個(gè)狀態(tài)可以有N個(gè)子狀態(tài)。這里不細(xì)講床嫌。
狀態(tài)機(jī)模式
狀態(tài)機(jī)模式定義
實(shí)現(xiàn)狀態(tài)機(jī)的一種方法就是狀態(tài)機(jī)模式(State Pattern)跨释,其定義如下:
定義一個(gè)狀態(tài)接口State,在外部事件message到來時(shí)厌处,State處理該事件并在其實(shí)現(xiàn)類之前轉(zhuǎn)移鳖谈。其時(shí)序圖如下:
下面我們將通過Android狀態(tài)機(jī)StateMachine來詳細(xì)講解這個(gè)模式的設(shè)計(jì)和使用。
Android狀態(tài)機(jī)
設(shè)計(jì)及實(shí)現(xiàn)
Android原生通過狀態(tài)機(jī)模式實(shí)現(xiàn)了一個(gè)分層狀態(tài)機(jī)名為StateMachine阔涉。其結(jié)構(gòu)如下:
一個(gè)狀態(tài)機(jī)對(duì)象缆娃,由一棵狀態(tài)樹,及實(shí)現(xiàn)狀態(tài)轉(zhuǎn)移并接收外部事件給當(dāng)前狀態(tài)處理的SmHandler構(gòu)成瑰排。其具體流程的時(shí)序圖如下:
1. 構(gòu)建一棵狀態(tài)樹(可多層)贯要。
2. 設(shè)置初始狀態(tài)。
3. 啟動(dòng)狀態(tài)機(jī)椭住。即崇渗,進(jìn)入初始狀態(tài),并完成初始狀態(tài)的enter action。
4. 狀態(tài)機(jī)收到一個(gè)外部事件宅广,并交由SmHandler處理葫掉,SmHandler通知當(dāng)前狀態(tài)處理事件,如果當(dāng)前狀態(tài)處理完這個(gè)事件后需要狀態(tài)轉(zhuǎn)移跟狱,則由SmHandler完成狀態(tài)轉(zhuǎn)移俭厚。
5. 退出當(dāng)前狀態(tài)時(shí),SmHandler通知當(dāng)前狀態(tài)處理exit action驶臊。進(jìn)入新狀態(tài)之前挪挤,SmHandler通知新狀態(tài)先處理其enter action。
6. SmHandler在通知當(dāng)前狀態(tài)處理事件前和狀態(tài)完成事件處理之后关翎,會(huì)回調(diào)StateMachine處理準(zhǔn)備和結(jié)束動(dòng)作扛门。
使用方法
狀態(tài)機(jī)的使用很簡(jiǎn)單,如圖
只需要建立一個(gè)StateMachine的實(shí)現(xiàn)類笤休,在這個(gè)實(shí)現(xiàn)類中創(chuàng)建State的各個(gè)實(shí)現(xiàn)尖飞,通過StateMachine#addState()構(gòu)建狀態(tài)樹,開啟狀態(tài)機(jī)店雅。
其具體流程可參考下圖:
應(yīng)用
具體應(yīng)用請(qǐng)參考?Android通話應(yīng)用設(shè)計(jì)?中關(guān)于CalAudioRouteStateMachine和CallAudioModeStateMachine的介紹政基。
原創(chuàng)內(nèi)容歡迎轉(zhuǎn)載,但請(qǐng)注明出處闹啦,謝謝沮明!