Key Principle
Coding a statechart is mechanical translation, not creative problem-solving. Each statechart element maps to a single code construct: one state variable per hierarchy level, one per concurrent region, one state procedure per state, and event handlers that only delegate to the control object. "Coding a statechart is a simple process that can be completed very quickly once the design has been finalized." (Chapter 13). If coding feels difficult, the design is incomplete.
Why This Matters
The coding phase is where the statechart method's investment pays off. Every state, transition, and guard condition was validated on paper before a line of code was written. The mechanical nature of the translation means the coding step itself becomes a verification gate: if you need a conditional inside a state procedure, or if you cannot map a user event to a single delegation call, the statechart has a gap. Implementation difficulty signals design deficiency, not implementation complexity.
Good Examples
Control object separation: "A control object controls and co-ordinates the behaviour of a set of user interface objects." (Chapter 13). Event handlers contain only a delegation call -- "No other code is contained in the event handlers." (Chapter 13). State variables are private to the control object, enforcing the statechart as the single source of truth.
State procedures without conditionals: State procedures always set the same attributes to the same values. "There should be no conditional statements which could cause different attributes to be set." (Chapter 13). If you need an
ifinside a state procedure, the statechart is missing states -- hidden behavioral variation was never designed.Transient states as routing nodes: Transient states update the state variable, evaluate conditions, and immediately call the next state procedure. "A transient state does not modify the attributes of any user interface objects." (Chapter 13). Conditional branching stays visible in the statechart rather than buried in procedural code.
Hierarchical entry with cascading calls: Entering a state with substates requires calling state procedures at every hierarchy level. Forgetting a level leaves child state variables stale -- the system appears to be in the parent state but the child-level configuration is undefined.
Explicit history variables: Before leaving a state group, store the current state variable in a dedicated
_historycompanion. "Storing the state variable in an explicit history variable is recommended because it is clear in the code that the state value is intended to be preserved." (Chapter 13). Use explicit history even when technically unnecessary -- making preservation visible and deliberate prevents accidental-preservation bugs during maintenance.Concurrency with independent state variables: Each concurrent region gets its own state variable. A single event may trigger transitions in multiple regions via independent conditional blocks. The correctness test: if you can swap the order of concurrent blocks without changing behavior, the concurrency is correctly implemented.
Debug window with step and continuous modes: A debug window displays all state and history variable values in real time. A step/continuous toggle pauses execution at each state entry. "Rarely will developers want to wade through a sequence of alert messages for every single state transition. It is more likely that they will want to get to the point which is causing problems and then step through the code transition by transition." (Chapter 13).
Counterpoints
Conditionals inside state procedures: Figure 13.3 shows the anti-pattern -- a conditional
go_state_48that signals a statechart defect. The fix is never to add the conditional but to return to the design and add the missing states.Sharing code across contexts: "If the same event can occur in two different contexts and the resulting actions are identical, it is still strongly advised that the code for the two events are kept separate." (Chapter 13). Minor duplication is cheap; cross-context side-effects during maintenance are expensive.
Misplaced actions in concurrent blocks: "If the delete action was associated with the other event instead...then the software would not work correctly. In this instance, state 1 would be entered before the record had been deleted." (Chapter 13). Reordering blocks to fix this would violate concurrency independence -- the real fix is correct action association at the design level.
Key Quotes
"Coding a statechart is a simple process that can be completed very quickly once the design has been finalized." -- Ian Horrocks, Chapter 13
"A control object controls and co-ordinates the behaviour of a set of user interface objects." -- Ian Horrocks, Chapter 13
"State procedures always set the same attributes to the same values. In other words there should be no conditional statements which could cause different attributes to be set." -- Ian Horrocks, Chapter 13
"To take full advantage of the statechart approach, it is strongly recommended that debugging code is included in all user interfaces as a matter of course." -- Ian Horrocks, Chapter 13
"Having a log of the precise state of the application at the point of failure can make tracking down errors much easier than normal." -- Ian Horrocks, Chapter 13
Rules of Thumb
- One state variable per hierarchy level, one per concurrent region -- no exceptions
- If a state procedure contains a conditional, the statechart is missing states; fix the design
- Event handlers contain exactly one thing: a delegation call to the control object
- Always use explicit history variables, even when the value would naturally be preserved
- Transient states never modify UI attributes; they evaluate conditions and delegate forward
- Test concurrency correctness by swapping block order; if behavior changes, there is a hidden dependency that must be resolved at the design level
- Include debug infrastructure (state display, step mode, post-mortem logging) as standard practice, not as an afterthought
- Keep code for identical behavior in different contexts separate to prevent maintenance errors
Related References
core-framework.md-- UCM architecture and control object separation that coding implementsstatechart-notation.md-- Design notation (hierarchy, concurrency, history) that maps to code constructs described herethree-artifact-specification.md-- The specification artifacts that precede and drive coding