State Machines Diagrams are used for behavioral modeling of the classes. State machines are based on states, transitions and events which trigger states transitions. Effects are parts of transitions which define responses to invocations triggered by signals. In other words – state machines give the possibility to model a set of reactions to different events, and the reaction involves effects and state changes.
To model a state machine properly for a class is more difficult than to implement the same functionality just as a set of methods and attributes in common way. Finally, actual state of the class is nothing more than another property of the class and transitions are in the same way just methods. You can define the behavior of the class fully with the programming language without use of state machines – the state machines are just technique to model class behavior more readably and graphically.
How to achieve the best state machine for the class?
The answer is: state transition table and iterative approach. State transition table is another notation of state machine used for verification of state machine’s completeness and an alternative view to state machine modeling quality. The main building blocks of the state transition table are States and Triggers. The cells describe proposed states of the class to the received triggers, which can be state, ignore, exception or defer clause.
Simplified Air Condition State Machine Sample
States: Heating, Cooling, Idle, StandBy, Malfunction.
Triggers: Increment Temperature, Decrement Temperature, Turn On, Turn Off, Reset, Temperature, Failure
State transition table “converted” 1:1 to state machine is on Fig 02.
The state machine covers all details of the state transition table, but contains redundancy, the readability of the diagram is poor and the diagram tends to be complicated.
State transition table without need of state machine draft shows the possible drawbacks of state machine design. Fig03 outlines what the state transition table shows before we start to draw state machine.
What is the outgoing Situation?(see Fig. 04)
- Turn Off leads always to StandBy (green)
- Increment and Decrement required Temperature triggers no change state, but always invokes the same effect (red)
- States Idle, Heating and Cooling have almost the same transitions (red)
- Temperature triggers the same decision for states Idle, Cooling, Heating (orange)
First point can be easily solved with use of history state, all transitions triggered with Turned Off are replaced with one transition triggered with Turned Off from History State, see Fig05.
To solve Points 2, 3, 4 you need to define what Use Cases the class realizes: starts and stops heating or starts and stops cooling based on comparison between required temperature and actual temperature, failure handling, temperature watching, required temperature handling. Try to identify which from these use cases are related to redundancy contained in state machine.
There are two ways how to solve it:
- create state machine “Turned On” which contains states “idle”, “cooling”, “heating” with self-transitions
- create a new class and required temperature handling delegate to this new class
Second way is better than the first one, because with the required temperature handling we can delegate together temperature watching into the new class called “Thermostat” – for the states of the new class refer to the Fig07.
The points 2, 3, 4 will be solved with move of transitions Increment Temperature, Decrement Temperature, Temperature and Decision Point into the new class, see Fig08.
The last step is to extend existing class AirCondition with new transitions “Start Cooling”, “Start Heating” and “Go to Idle” which are triggered with the new effects defined inside of the new class Thermostat, see Fig09.
To summarize rules through this sample:
- model your state machine in the most simple way
- always sketch a state table, not only for prototyping, but for every change you implement in your state machine
- model state machines in order to define how the class collaborates with other classes
- prevent modeling of internal transitions
- if state table contains cells with “ignore” or “defer” you are on wrong way
- prevent to trigger transition inside the class
- use history state, do not model transition from all states
- if state machine contains redundancy, try to delegate this functionality out of the class
- do not design more than 8 states and 16 transitions inside state machine and maximum 3 levels of depth
- do not prefer state machine modeling over the object-oriented approach of class modeling