Created
November 8, 2012 15:14
-
-
Save anonymous/4039400 to your computer and use it in GitHub Desktop.
State machine convention
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* State names are described as a enum or string constants if language doesn't support them (as3 for example). | |
*/ | |
private enum State { | |
A, B, C | |
} | |
/** | |
* Current state is always private. If previous state is needed add | |
* private State prevState; | |
*/ | |
private State state; | |
/** | |
* All state transitions are done by calling methods stateSomething(); | |
* These methods first can execute special logic for previous state (specific for previous state -> new state transition. | |
* After that they call setState(newValue) and execute state specific logic. | |
*/ | |
void stateA() { | |
switch (state) { | |
case State.B: | |
break; | |
} | |
setState(State.A); | |
// State A enter logic | |
} | |
/** | |
* A state can have additional parameters which are passed to state change function: | |
* stateB(0); | |
*/ | |
void stateB(int data) { | |
setState(State.B); | |
// State B enter logic | |
} | |
void stateC() { | |
setState(State.C); | |
// State C enter logic | |
} | |
/** | |
* Usually setState is just: | |
* state = value; | |
* or plus prevState = state; if you need to store previous state. | |
* But it may contain generic state exit logic. | |
*/ | |
void setState(State value) { | |
switch ( state ) { | |
case State.A: | |
// state A exit logic | |
break; | |
// other states | |
} | |
state = value; | |
} | |
/** | |
* Event handlers look like this. Doing only what actions are allowed in current state. | |
*/ | |
void event1Handler() { | |
switch (state) { | |
case State.A: | |
// state A logic | |
break; | |
// other states | |
} | |
} | |
/** | |
* What this convention helps to acomplish: | |
* - Most of state logic is usually in enter functions. This convention allows to split giant setState(State value) method with lots of switch case statements into small methods. | |
* - Actual state change can happen only through stateBla() call and can be easily debugged. | |
* - States can accept parameters, for example you got a BookOpenedAtPage state which you set by calling stateBookOpenedAtPage(42). | |
* - In event handlers it is obvious what logic is executed in every state. | |
* - Every team member knows where to put enter state and exit state logic. The later usually is much less used but can be moved to separate methods if setState grows out of control. | |
* - No framework and configuration needed. | |
* - Can hack stuff at the last moment. Though not recommended. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment