Key Principle
A complete behavioral specification of a user interface requires three coordinated artifacts: the statechart diagram, the event-action table, and the state-item table. No single artifact is sufficient. The diagram shows state structure visually; the event-action table specifies transition behavior precisely; the state-item table maps each state to its UI presentation. The complete design lives across all three, and each artifact compensates for the weaknesses of the others.
Why This Matters
Statechart diagrams alone are incomplete specifications. Space constraints prevent fitting all event, condition, action, and state-definition details into a diagram. But tables without diagrams would be difficult to understand and modify. The three-artifact approach resolves this tension:
- Statechart diagram: Provides navigational comprehension -- state structure at a glance, hierarchy, concurrency regions, and transition flow. It is "an abstract view of the design," not the design itself.
- Event-action table: Provides behavioral precision -- for every transition, the exact current state, triggering event, guard condition, actions performed, and next state. This is what developers code from.
- State-item table: Provides presentation completeness -- for every state, what the user sees: which items are enabled, disabled, visible, hidden, or have changed properties.
Dropping any one artifact creates a gap -- ambiguous behavior, unreadable structure, or undocumented UI changes scattered through code. The separation is a deliberate design choice: diagrams stay visually comprehensible because they show only flow structure, while the tables preserve full specification rigor.
Good Examples
Diagram-table split (Chapter 6): A transition reads "if event 1 occurs in state A and condition C is true, then transition to state B." The diagram captures this flow visually. The companion event-action table records what each transition actually does: guard conditions, side-effect actions, and next state. Table 6.1 demonstrates a row: Current state = 10, Event = "Create button clicked and (status field = 'X')", Actions = "Insert data P into database table Q; Commit the database transaction", Next state = 6.
Modular event-action tables (Chapter 7): A monolithic table for an entire application fails because too many state variable columns make it unreadable and a single table prevents parallel development. The solution: each screen or major statechart region gets its own event-action table with only its relevant state variables. Transitions between regions are captured in dedicated interface tables, identifiable by a mechanical test -- the state variables in the "Current state" column differ from those in the "Next state" column. Figure 7.2 decomposes into four tables: Summary screen, Details screen, and two interface tables linking them.
State variables as design artifacts (Chapter 7): A state variable is assigned to every state that contains sub-states. In concurrent regions, each region maintains its own variable simultaneously. The labeling convention is <State ID> <State Name> <[State variable]>. When the user is in a state with three concurrent parts [D], [E], [F], all three variables plus their ancestors are active. These variables must be assigned during design, not deferred to coding, because event-action tables cannot be precise without them.
State-item tables beyond enabled/disabled (Chapter 7): Real applications change coordinates, dimensions, color, font, visibility, format masks, labels, icons, dropdown contents, and required-field status based on state. If these changes are not captured in state-item tables, they become implicit, scattered through code, and undocumented.
Counterpoints
- For trivially simple interfaces (one screen, no concurrency, few states), maintaining three synchronized artifacts may be overhead that outweighs the benefit. The author's examples involve business applications with hierarchical and concurrent state structures.
- The three artifacts must be maintained in sync. The diagram alone is an incomplete specification, and if the tables diverge from the diagram, the specification contradicts itself. This synchronization cost is the primary practical objection.
- The event-action table should remain abstract -- describing what the software does, not how. If tables contain implementation-level detail (specific procedure names, code syntax), every code refactoring forces a specification update and the two drift apart.
Key Quotes
"The event-action tables and state-item tables provide the complete specification of the statechart. The pictures of statecharts can only be an abstract representation of the software because it is usually impossible, through lack of space, to fit all the necessary details into the diagrams." (Part 3 Introduction)
"State variables are required during the design process so that each transition can be identified accurately in event-action tables. By having precise event-action tables, translating the design into code is made easy." (Chapter 7)
"It is recommended that the event-action table should be written as an abstract specification rather than one that is syntactically consistent with the code. The table should show what the software does rather than how it is actually done." (Chapter 7)
"If the characteristics of an item change during the execution of the application then these changes should be captured in states." (Chapter 7)
"The aim should be to have tables with no more than about 5 or 6 state variables." (Chapter 7)
Rules of Thumb
- The diagram is not "the design" -- it is an abstract view of the design. The complete design lives across diagram, event-action table, and state-item table together.
- Keep event-action tables modular: aim for no more than 5-6 state variables per table. Decompose by screen or statechart region.
- Use interface tables to capture cross-module transitions. The mechanical test: current-state variables differ from next-state variables.
- Assign state variables during design, not during coding. Imprecise tables produce ambiguous code.
- Cluster states (introduced solely for arrow reduction) get no identifiers and do not appear in event-action tables. Only leaf-level states receive numerical identifiers.
- Keep event-action tables abstract -- describe what, not how -- so they survive code refactoring without drifting from the specification.
- Any UI property that changes based on state belongs in the state-item table, not just enabled/disabled status.
Related References
- Statechart depth and hierarchy (Chapter 6): refinement vs. clustering, and why depth is the fundamental differentiator from flat state machines. Clustering states are a diagram-only convenience -- they receive no identifiers and do not appear in event-action tables.
- Design heuristics (Chapter 9): guard conditions as state discriminators, unconditional actions, and simultaneous event order independence all depend on the three-artifact framework being complete and precise.
- Concurrent regions and orthogonal state variables (Chapters 6-7): each concurrent region requires its own state variable, directly driving the need for modular table decomposition.