A state diagram, also known as a state machine diagram, is a fundamental behavioral diagram within the Unified Modeling Language (UML) that illustrates the dynamic behavior of an object, system, or interaction over its lifetime. It models the sequence of states an object goes through in response to events, showing its current state, how it reacts to events, and the transitions between states. This visual representation is crucial for understanding the lifecycle of an entity, particularly in complex reactive systems, embedded systems, and user interfaces, where the system’s response is highly dependent on its current condition.
The primary purpose of a state diagram is to specify the behavior of individual classifier instances, such as objects, components, or use cases. It captures the essential characteristics of a system’s dynamic behavior, providing a clear and unambiguous way to define how a system changes its condition over time. By mapping out all possible states and the events that trigger transitions between them, state diagrams help in identifying potential issues, ensuring completeness in design, and facilitating communication among stakeholders, from requirements gathering to system implementation and testing. They are invaluable tools for designing robust and predictable systems that respond appropriately to various inputs and internal changes.
Elements of a State Diagram
State diagrams are composed of several key elements that collectively describe the behavior of a system or object. Each element plays a distinct role in defining the system’s condition, the events that trigger changes, and the actions performed during these changes.
States
A state represents a condition or situation during the lifetime of an object or an interaction during which it satisfies some condition, performs some activity, or waits for some event. It is a stable configuration of attributes and relationships that a system can occupy for a period of time. In UML, a state is typically drawn as a rounded rectangle.
- Name: Every state must have a unique name that describes the condition or situation it represents (e.g., “Idle,” “Processing,” “Active”).
- Internal Activities: A state can specify activities that occur while the system is in that state. These include:
entry / [action](/posts/what-is-action-of-m-cpba-on-trans-but-2/)
: An action executed immediately upon entering the state.exit / action
: An action executed immediately upon exiting the state.do / activity
: An ongoing activity that is performed as long as the system remains in the state. This activity can be interrupted by an event that triggers a transition out of the state.event / action
: An internal transition, meaning an action triggered by an event while in the state, without causing a state change. This is useful for handling events that don’t alter the state but require some response.
Types of States:
-
Simple State: This is the most basic type of state, having no internal structure or concurrent regions. It represents a single, atomic condition of the system.
-
Composite State (Nested States): A state that contains other states (sub-states), effectively representing a nested state machine. This allows for hierarchical modeling, breaking down complex behaviors into more manageable sub-behaviors.
- Sub-states: States nested within a composite state. A composite state is entered, and then one of its sub-states is entered, following its own internal transitions.
- Orthogonal Regions (Concurrent States): A composite state can be divided into two or more independent regions, separated by dashed lines. Each region contains its own sub-state machine, and all regions execute concurrently. This is used to model parallel behaviors within a single logical state. For example, a “Car Moving” state might have orthogonal regions for “Engine Status” (Running, Off) and “Window Status” (Open, Closed).
-
Initial State (Start State): Represented by a solid black circle, this pseudo-state denotes the beginning of the state machine’s execution. Every state machine must have exactly one initial state, from which the first transition originates to the default starting state.
-
Final State (End State): Represented by a solid black circle surrounded by an outer circle, this pseudo-state indicates the completion of the state machine’s execution. When a system reaches a final state, its behavior ends. Not all state machines require a final state, especially those modeling continuous processes.
-
History State: A pseudo-state represented by a circle containing an ‘H’ (for shallow history) or ‘H*’ (for deep history). A history state remembers the last active sub-state of its containing composite state.
- Shallow History (H): When a system re-enters a composite state via a transition to a shallow history pseudo-state, it re-enters the immediate sub-state that was active before it exited the composite state.
- Deep History (H):* Similar to shallow history, but it remembers the specific state nested to any level of depth within the composite state. This allows for restoration of a precise configuration of nested sub-states.
Transitions
A transition is a relationship between two states, indicating that an object in the first state (source state) will perform certain actions and enter the second state (target state) when a specified event occurs and specified conditions are satisfied. Transitions are represented by an arrow from the source state to the target state.
The label on a transition typically follows the format: event [guard condition] / action
.
- Event: An occurrence that can trigger a transition from one state to another. Events are fundamental to state machine behavior, as they are the stimuli that cause state changes.
- Signal Event: Asynchronous communication where an object sends a signal to another object (e.g.,
buttonPressed()
). - Call Event: Synchronous invocation of an operation on an object (e.g.,
depositMoney()
). The transition occurs upon the completion of the operation. - Change Event: A transition triggered when a specified condition becomes true (e.g.,
when(temperature > 100)
). The condition is continuously monitored. - Time Event: Occurs after a specified time interval or at a specific date/time (e.g.,
after(5s)
,at(midnight)
).
- Signal Event: Asynchronous communication where an object sends a signal to another object (e.g.,
- Guard Condition: A Boolean expression that must evaluate to
true
for a transition to occur. If the guard condition isfalse
when the event occurs, the transition does not fire, and the event is effectively ignored for that specific transition path. Guards are enclosed in square brackets[]
(e.g.,[balance >= cost]
). Multiple transitions leaving the same state for the same event can have different guards, allowing for conditional routing. - Action: An atomic, non-interruptible operation executed during a transition. Actions are executed once the guard condition is met and before entering the target state. These are different from state activities (
entry
,exit
,do
) as they occur during the change itself. Actions are specified after a forward slash/
(e.g.,/ dispenseProduct()
).
Pseudo-states (Connectors and Control Flow)
Pseudo-states are special nodes in a state diagram that control the flow of transitions but are not actual states where a system can reside for an extended period.
- Choice Pseudo-state (Junction): Represented by a diamond shape, a choice pseudo-state allows for dynamic conditional branching based on run-time conditions. An incoming transition leads to the choice point, and multiple outgoing transitions, each with its own guard condition, determine the next state. Only one outgoing transition can be taken based on the guards.
- Fork Pseudo-state: Represented by a thick bar, a fork pseudo-state allows a single incoming transition to split into multiple concurrent outgoing transitions. Each outgoing transition leads to a different region within a composite state, initiating parallel execution of sub-state machines. All outgoing transitions from a fork must be taken simultaneously.
- Join Pseudo-state: Also represented by a thick bar, a join pseudo-state synchronizes multiple concurrent incoming transitions into a single outgoing transition. All incoming transitions must reach the join point before the outgoing transition can fire, effectively waiting for parallel activities to complete.
- Terminate Pseudo-state: Represented by a cross (X) within a circle, a terminate pseudo-state indicates that the execution of the state machine ceases and the containing object or system is destroyed or ends its lifecycle. No further transitions are possible from a terminate state.
- Entry Point / Exit Point: These are connection points used to enter or exit a composite state from outside its boundaries.
- Entry Point: A small circle on the boundary of a composite state with an incoming transition. It specifies a particular sub-state to be entered when the composite state is entered via this point.
- Exit Point: A small circle on the boundary of a composite state with an outgoing transition. It indicates a specific point where control leaves the composite state.
Regions
Regions are used within composite states to model orthogonal (concurrent) sub-state machines. A composite state can be divided into multiple regions, each of which contains an independent state machine that executes in parallel with the others. For example, a “Car” composite state could have regions for “Engine Status” and “Gearbox Status” running concurrently. A dashed line separates regions within a composite state. All sub-state machines within orthogonal regions are active simultaneously when the composite state is entered.
Example of a State Diagram: Vending Machine
Let’s illustrate the elements of a state diagram with an example of a simple Vending Machine. This machine allows users to insert coins, select a product, dispense the product, and receive change. It also handles basic error conditions and timeouts.
Vending Machine State Diagram Description
The Vending Machine state diagram models the dynamic behavior of the machine from the perspective of a user interaction.
1. Initial State:
- The diagram begins with an Initial State (solid black circle), indicating the start of the vending machine’s operational lifecycle.
- From the Initial State, there is an unconditional transition to the
Idle
state, signifying that the machine starts in an awaiting state.
2. Idle
State:
- This is the default state where the machine waits for user interaction.
- Entry Action:
display "Insert Coin"
: Upon entering this state, the machine’s display prompts the user to insert money. - Transition:
InsertCoin(amount)
/add_to_current_balance(amount)
: When a user inserts a coin (theInsertCoin
event with anamount
parameter), the machine adds the amount to its internal balance, and transitions to theCollecting Money
state.
3. Collecting Money
(Composite State):
- This is a Composite State because it contains nested sub-states, reflecting more granular behavior while money is being collected.
- Entry Action:
do / update_display_balance()
: The machine continuously updates the display with the current balance while in this state. - Internal Transition:
InsertCoin(amount)
/add_to_current_balance(amount)
: If more coins are inserted while already inCollecting Money
, theamount
is added, and the machine remains in theCollecting Money
state. This is an example of an internal transition or a self-transition, where the state doesn’t change, but an action is performed. - Transition (Exit Conditions):
Cancel
->Returning Change
: If the user presses a “Cancel” button, the machine transitions toReturning Change
.after(60s)
->Returning Change
: A Time Event triggers a transition toReturning Change
if no activity occurs for 60 seconds (a timeout).
- Sub-states within
Collecting Money
:Awaiting Selection
:- Entry Action:
display "Select Product"
: Once the user has inserted at least some money, the machine prompts for product selection. This is the default entry point into theCollecting Money
composite state. - Transition (Conditional):
SelectProduct(code)
:[has_sufficient_funds(code) and is_product_available(code)]
/deduct_product_cost(code)
->Dispensing Product
: If theSelectProduct
event occurs, and the Guard Condition[has_sufficient_funds(code) and is_product_available(code)]
is true, the machine deducts the product cost and transitions toDispensing Product
.[not has_sufficient_funds(code)]
->Insufficient Funds
: If the selected product costs more than the current balance, the machine transitions to theInsufficient Funds
sub-state.[not is_product_available(code)]
->Awaiting Selection
/display "Product Unavailable"
: If the selected product is out of stock, the machine remains inAwaiting Selection
and displays a message. This is another internal transition/self-transition with an action.
- Entry Action:
Insufficient Funds
:- Entry Action:
display "Need More Money"
: The machine informs the user about insufficient funds. - Transition:
InsertCoin(amount)
->Awaiting Selection
/add_to_current_balance(amount)
: If the user inserts more money, the balance is updated, and the machine moves back toAwaiting Selection
. - Transition:
Cancel
->Returning Change
: The user can still cancel and get their money back.
- Entry Action:
4. Dispensing Product
State:
- This state represents the machine in the process of releasing the selected item.
- Do Activity:
do / dispense_product()
: While in this state, the machine continuously performs the action of dispensing the product. - Transition:
ProductDispensed
->Returning Change
: Once the product has been successfully dispensed (theProductDispensed
event), the machine transitions toReturning Change
. - Transition (Error):
ProductJam
->Error
: If the product gets stuck during dispensing (aProductJam
event), the machine transitions to theError
state.
5. Returning Change
State:
- This state handles the payout of any remaining balance to the user.
- Do Activity:
do / return_change()
: The machine performs the action of returning change. - Transition:
ChangeReturned
->Idle
: Once the change has been successfully returned (theChangeReturned
event), the machine goes back to theIdle
state, ready for the next customer.
6. Error
State:
- This state is entered when a significant malfunction occurs, such as a product jam or an internal system error.
- Entry Action:
display "Error. Call Support."
: The machine indicates an error condition. - Transition:
Reset
->Idle
: The only way to exit theError
state is typically through a manualReset
event, which brings the machine back toIdle
.
7. Final State:
- While not explicitly shown as reachable in the normal flow (as vending machines typically operate continuously), a final state (bullseye symbol) could be used if the machine had a specific “shutdown” or “decommissioned” lifecycle stage. In this continuous operational model, the machine often loops back to
Idle
.
This vending machine example demonstrates how states, transitions, events, guards, actions, and composite states work together to model a system’s dynamic behavior comprehensively. It shows how different events can lead to different outcomes based on the machine’s current state and specific conditions.
Conclusion
State diagrams are powerful graphical tools in system design and analysis, providing a clear and comprehensive visualization of the dynamic behavior of objects or systems. By explicitly defining the various conditions an entity can be in (states) and how it reacts to external stimuli or internal changes (events and transitions), these diagrams reveal the intricate flow of control and data within a system. They offer a precise and unambiguous way to model reactive systems, ensuring that all possible scenarios are considered and that the system responds predictably to all inputs and circumstances.
The detailed elements of a state diagram—including various types of states (simple, composite, initial, final, history), transitions governed by events, guards, and actions, and pseudo-states like choices, forks, and joins—enable developers and stakeholders to capture even the most complex behavioral patterns. This systematic approach not only aids in the initial design phase by uncovering potential deadlocks or unreachable states but also serves as an invaluable reference during implementation, testing, and maintenance. The clarity and expressiveness of state diagrams make them an indispensable asset for effective communication among technical and non-technical team members, fostering a shared understanding of system dynamics.
Ultimately, mastering the construction and interpretation of state diagrams empowers engineers to build more robust, reliable, and user-friendly systems. Their application extends across various domains, from software development and embedded systems to business process modeling, underscoring their universal utility in describing any entity that undergoes changes in response to discrete events. By rigorously mapping out state-dependent behaviors, state diagrams significantly reduce ambiguities and enhance the quality and correctness of system designs.