Nested States
The UML2 specification allows for the concept of a nested state.
Nested states exist to reduce exponential 'state' and 'transition' explosions that can occur with classic FSMs.
Let's look at a code example and the associated diagram.
In the above code block the indentations show the level of nesting. You can see that the state 'Young' is nested within the state 'Alive'.
Each box represents a State and its nested states. In the above diagram we have two top level states 'Alive' and 'Dead'.
You can see how the 'Young' state is nested within the 'Alive' state box which reflects the above code.
There is no limit to the depth of nesting.
Leaf States
States that have no child states of their own are referred to as Leaf States.
When looking at a nested state diagram, the top state(s) are the root state(s) and any states that are at the end of a branch are the leaf states. So in the above diagram Alive and Dead a root states and Buddhist and Old are leaf states.
Due to the limits of the dot diagraming tooling (or my ability to use it) the grey ovals are duplicates of the box. The State 'Alive' is also represented by a box and the grey oval 'Alive'. This is done so that transitions to the parent state can be easily represented on the diagram.
Abstract States
When you create a nested set of states any states that have children states becomes 'abstract' states.
You cannot transition to an abstract state!
In the above example each of 'the Alive', 'Dead', 'InHeavan', 'InHell' and 'Christian' states have children states and are therefore abstract states.
It is only valid to create a transition to a Leaf state.
A Nested FSM can be in multiple states!
When an FSM is in a Nested State we say that it is also in ALL ancestor states.
A classic FSM can only ever be in a single state, Nested States make life more interesting >:) *2
As an example; if the above FSM transitions to the 'Catholic' state we say that the FSM is in the 'Catholic' state, 'InHell' state and the 'Dead' state simultaneously.
If you call StateMachine.isInState<Dead>() or StateMachine.isInState<InHell>() both will return true.
Cascading Events
If a parent state has a transition then we say that the child state also has that transition.
Let's look at a toaster oven that supports toasting and baking and that turns off the heater when the door is open.*1
In the above example the transition ..on<OpenDoor, DoorOpen> is duplicated for both the Toasting and Baking state.
If we create a super state Heating
we can then make it the parent of Toasting
and Baking
.
We can now attached the .on<OpenDoor, DoorOpen> transition to the Heating
state.
Both Toasting and Baking now inherit the .on<OpenDoor, DoorOpen> transition from the Heating state.
This is the result:
This may not seem much of a saving but when you have an FSM with a significant no. of States and events then Nested States significantly reduce the complexity of an FSM.
*1 Example sourced from: https://www.embedded.com/a-crash-course-in-uml-state-machines-part-2/
*2 Evil grin
Last updated