What do we do if the state is constantly switching and changing during the run?
The migration of State is a very common concept in our life and engineering. So there is a theory in mathematics to analyze and solve this problem.
Finite state machine theory is a very mature theory, the migration of all movements and processes can be attributed to the migration of the state.
The premise of this theory is:
The number of States is deterministic, or limited.
The migration direction of the state is fixed, that is, directed.
State stores information about the past, which means that it reflects input changes from the beginning of the system to the present moment. The transfer indicates a state change and describes it with conditions that must be met to make the transfer happen. An action is a description of the activity to be performed at a given moment. There are several types of actions:
Enter action (entry action): When entering a state
Exit action: When exiting a state
Input action: dependent on the current state and the input conditions
Transfer action: In the case of a specific transfer
Below we will follow the operation of a subway mill to explain the theory of wired state machine.
The overall state diagram of the Metro Mill is as above. The basic is to open and close 2 kinds of behavior.
There are 3 ways to implement an FSM.
1.switch Case Mode
Packagecom.joyfulmath.state.switchcase;/** * @authorDeman.lu *@versionOn 2016-05-18 09:43*/ Public classturnstile {//Status Public Static Final intLOCKED = 0; Public Static Final intUnlocked = 1; //Events Public Static Final intCOIN = 0; Public Static Final intPASS = 1; intState =LOCKED; PrivateTurnstilecontroller Turnstilecontroller; Publicturnstile (Turnstilecontroller turnstilecontroller) { This. Turnstilecontroller =Turnstilecontroller; } Public voidEnent (intevent) { Switch(state) { CaseLOCKED:Switch(event) { Casecoin:state=unlocked; Turnstilecontroller.unlock (); Break; CasePASS:turnstileController.alarm (); Break; } Break; CaseUnlocked:Switch(event) { CaseCOIN:turnstileController.thankYou (); Break; Casepass:state=LOCKED; Turnstilecontroller.lock (); Break; } Break; } }}
/**@author@version * * Public interface Turnstilecontroller { void lock (); void unlock (); void alarm (); void thankyou ();}
The migration of the state is carried out in the Switch-case statement. Currently there are 2 states & 2 trigger conditions.
Switch-case is the result of 2*2. Can meet, if the situation is complicated, switch-case will show explosive growth.
2. Interpreting the Migration table
This method was common in the early C language, and I personally experienced the code and maintained it for a while.
To tell you the truth, this thing is a little C language to implement object-oriented thinking. Of course, the Java language cannot be compared.
Packagecom.joyfulmath.state.switchcase;Importjava.util.ArrayList;Importjava.util.List;/** * @authorDeman.lu *@versionOn 2016-05-18 10:05*/ Public classTurnstyle {intState =turnstile.locked; Turnstilecontroller Turnstilecontroller; List<Transition> mtransitions =NewArraylist<>(); PublicTurnstyle (FinalTurnstilecontroller Turnstilecontroller) { This. Turnstilecontroller =Turnstilecontroller; Addtransition (turnstile.locked, Turnstile.coin, turnstile.unlocked,NewRunnable () {@Override Public voidrun () {turnstilecontroller.unlock (); } }); } Private voidAddtransition (intStateintEventintnextstate, Runnable Runnable) {Transition Transition=NewTransition (); Transition.currentstate=State ; Transition.event=event; Transition.nextstate=nextstate; Transition.runnable=runnable; Mtransitions.add (transition); } Public voidEventintevent) { for(Transition transition:mtransitions) {if(Transition.currentstate = = state && Event = =transition.event) { state=transition.nextstate; Transition.runnable.run (); } } }}
Maintenance of the migration table is somewhat difficult. A bit of a large number of States & events exist, and the table will be very complex.
3.state mode
Fortunately, in software development, there is a design pattern for this gift. Using state mode is a very good way to implement an FSM today.
Package Com.joyfulmath.state.statemode; /** @author @version */public interface iturnstitlestate { void coin (turnsstatus t); void Pass (Turnsstatus t);}
This is the event.
Implementation of the State:
PackageCom.joyfulmath.state.statemode;/** * @authorDeman.lu *@versionOn 2016-05-18 10:52*/ Public classLockedstatusImplementsiturnstitlestate {@Override Public voidcoin (Turnsstatus t) {t.setunlock (); T.unlock (); } @Override Public voidPass (Turnsstatus t) {t.alarm (); }}
PackageCom.joyfulmath.state.statemode;/** * @authorDeman.lu *@versionOn 2016-05-18 10:53*/ Public classUnlockedstatusImplementsiturnstitlestate {@Override Public voidcoin (Turnsstatus t) {t.thankyou (); } @Override Public voidPass (Turnsstatus t) {t.setlock (); T.lock (); }}
Turnsstatus is the key to drive State migration. In some books that introduce state patterns, this class is generally defined as the context
PackageCom.joyfulmath.state.statemode;ImportCom.joyfulmath.state.switchcase.TurnstileController;/** * @authorDeman.lu *@versionOn 2016-05-18 10:52*/ Public classTurnsstatus {Private StaticIturnstitlestate Lockedstatus =NewLockedstatus (); Private StaticIturnstitlestate Unlockedstatus =NewUnlockedstatus (); PrivateTurnstilecontroller Controller; PrivateIturnstitlestate State =Lockedstatus; PublicTurnsstatus (Turnstilecontroller Controller) { This. Controller =Controller; } Public voidcoin () {State.coin ( This); } Public voidPass () {State.pass ( This); } Public voidSetlock () { state=Lockedstatus; } Public voidSetunlock () { state=Unlockedstatus; } voidthankyou () {controller.thankyou (); } voidAlarm () {controller.alarm (); } voidLock () {controller.lock (); } voidunlock () {controller.unlock (); }}
Where the coin & pass method is for external classes to be called, and
void unlock () { controller.unlock (); }
These methods are handled by the state.
State mode completely separates the logic and action of the state machine.
Actions are implemented in the context class, and the logic is implemented in each state.
From a personal experience, the state pattern is suitable for scenes where the state is repeatedly switched.
Reference:
"Agile Software Development" Uncle Bob.
Agile Software Development (1)---state mode