Part V

State Machines

How to draw the whole life of one object: the states it rests in, the events it reacts to and the transitions between them. The exam gives you a few numbered sentences and asks for a domain-level state machine worth 15 marks, so this Part builds that skill from the notation up.

  • You willknow when a state machine is worth drawing, and at which level (domain, use case or design).
  • You willread and draw every symbol: event [guard] / action, choices, composite states, history and regions.
  • You willturn numbered requirement sentences into a correct diagram, step by step, like the 2021 exam answers.
  • You willmap a state machine onto a design class and Java code, with an enum or the State pattern.
5.1

What a State Machine Is

Every diagram you have met so far shows behaviour only partly. A domain model or a design class diagram is static: it shows structure and says nothing about time. A system sequence diagram or a design sequence diagram does show time, but only one scenario, one particular run. A state machine fills the gap: it shows every legal ordering of events for one object (or one whole system) in a single picture. It is the course's model of dynamic behaviour over time.

Class diagrams structure only: no time at all Order Item what exists, how it is connected Sequence diagrams, SSDs time, but only one scenario :A :B one particular run, top to bottom State machine every legal ordering, for one object Idle Active Paused all the paths at once
Why another diagram? Static diagrams have no time in them, and a sequence diagram is one path. A state machine is the only one that shows all the paths an object can take through its life.

The six core terms exam

Six words come up in every state machine question. They are best learnt on one small example, Larman's telephone, which is either Idle (receiver on the hook) or Active (receiver lifted).

Definitions you can quote

State machine: a behaviour model that captures the dynamic behaviour of an object in terms of states, events and state transitions. Example: a telephone that switches Idle ⇄ Active.

State: the condition of an object at a moment in time; in Larman's words, "the time between events". The phone is Idle from when the receiver is put down until it is lifted again.

Event: a significant or noteworthy occurrence that may cause the object to change state, such as off hook.

Transition: a directed relationship between two states: when the event occurs, the object moves from the source state to the target state. On off hook, the phone goes from Idle to Active.

Guard: a boolean condition on a transition. The transition fires only if the guard is true when the event occurs, so it acts as a pre-condition, e.g. [valid subscriber].

Transition action: behaviour executed when the transition fires. In software it is usually a call to a method of the class that owns the machine, e.g. / play dial tone.

Idle Active off hook [valid subscriber] / play dial tone on hook 1 2 3 4 5 6
Every term in one picture. Throughout this page, events are blue, guards violet and actions green in the teaching diagrams. Read the top arrow as: "in Idle, if off hook occurs and the subscriber is valid, play the dial tone and move to Active".
  1. State: a rounded rectangle; the object rests here between events.
  2. Event: what happened (off hook). It triggers the transition.
  3. Guard: in square brackets; checked when the event arrives. If it is false, nothing happens.
  4. Action: after a slash; done instantly as the transition fires.
  5. Transition: the arrow itself, from the source state to the target state. This one carries only an event.
  6. Initial pseudostate: the filled dot that says where the life begins.

What the diagram does not have to show

Put together, a state machine shows an object's lifecycle: which events it reacts to, which transitions they cause, and which states it rests in between events. It does not have to show every possible event, because an event that is not drawn for the current state is ignored (Larman 29.1). That is why you can model at any level of detail, and why you never draw "do nothing" loops for irrelevant events.

The Workshop 6 sheet adds two points. First, a state can stand for a range of values: the colour of a traffic light is a state, but so is "fund > 0". Second, the diagram should cover the full lifecycle of the object, at a level of detail that matches the model it supports (the use case, SSD or class it explains).

digit event arrives Idle off hook … ✕ ignored No digit arrow leaves Idle, so nothing happens: the phone simply stays Idle.
Undrawn means ignored. You never need a "do nothing" self-loop for an irrelevant event.
Suspended Active available funds changed [available fund > 0] A state can be a range of values: here the condition "fund > 0", not one particular balance.
A state is a condition, not a single value. From the Workshop 6 credit-card account: the guard decides which range the object is in.
Check yourselfIn the label off hook [valid subscriber] / play dial tone, which part is the event, which the guard and which the action? What happens if the subscriber is not valid?

off hook is the event (the trigger), [valid subscriber] is the guard and / play dial tone is the action. If the guard is false when off hook occurs, the transition does not fire; since no other transition from Idle handles off hook, the event is ignored and the phone stays Idle, with no dial tone.

Check yourselfThe phone is Active and an off hook event somehow arrives. The diagram has no off hook arrow leaving Active. Is the diagram incomplete?

No. An event that is not drawn for the current state is simply ignored (Larman 29.1), so the phone stays Active. A state machine is allowed to leave out events that have no effect; adding a "do nothing" loop would only clutter it.

In short

A state machine shows one object's whole lifecycle: states (conditions between events), events (noteworthy occurrences) and transitions labelled event [guard] / action. Events that are not drawn for the current state are ignored, so you only draw what matters.

5.2

When to Draw One, and at Which Level

A state machine takes effort, so the first question is whether an object deserves one. The answer depends on one property: does the object's response to an event depend on its current state? This section gives Larman's two guidelines, the two broad kinds of use, the three levels a machine can be drawn at, and the kinds of event you can put on an arrow.

State-dependent and state-independent objects exam

An object is state-independent (modeless) with respect to an event if it always responds to that event in the same way. If it reacts the same way to every event of interest, it is a state-independent object, and a state machine adds nothing: it would be one state with self-loops. A state-dependent object, on the other hand, reacts differently to the same event depending on its current state or mode. Pressing a phone button, for example, means different things when the phone is on-hook, off-hook or in a menu.

State-dependent: worth a state machine On hook Off hook In a menu button pressed button pressed button pressed reaction A reaction B reaction C State-independent: not worth one Object event same reaction Whatever has happened before, the response is always the same.
The test is "same event, different response?" If the answer depends on the mode the object is in, the modes are states and a state machine earns its place.
Larman's two guidelines

Guideline 1. Consider state machines for state-dependent objects with complex behaviour, not for state-independent objects.

Guideline 2. Business information systems have few complex state-dependent classes, so a state machine rarely helps there. Process control, device control, protocol handlers and telecommunications have many, so in those domains you should always consider state machines.

Guideline 2 explains the exam: both past questions are control systems, a CO2 filter and a garage door.

Business information systems few complex state-dependent classes (a few exceptions, such as an Order or Sale) rarely useful more state- dependence Control and communication process control, device control, protocol handlers, telecommunications always consider both 2021 exam questions
Guideline 2 as a picture. The further a system is from "store and display records", the more state machines it needs.

The two broad applications (Larman 29.3)

Larman groups the uses of state machines into two families. The first is objects that react to events in complex ways; the second is protocols and legal sequences, where the machine says which operations are allowed when. The second is really a special case of the first, in which the "object" is a protocol, a language or a process.

Uses of state machines 1. Complex reactive objects behaviour is a response to events Physical devices controlled by software phone, car, microwave, garage door, CO₂ filter Transactions and business objects Sale, Order, Payment, Package: "what happens to an Order if a cancel event occurs?" Role mutators objects that change role, one state per role (a civilian becomes a veteran) 2. Protocols and legal sequences which operations are legal when Communication protocols: TCP ignores close when Closed UI page flow / navigation: pages are states, clicks are events ("Web Page Navigation") UI flow controllers, sessions: server-side Use case system operations: legal order of makeNewSale, enterItem, endSale, makePayment Window event handling: Edit→Paste only if the clipboard is non-empty
Two families. Left: things that react. Right: rules about what may happen next. Business objects like an Order sit on the left, which is why Tony's Pizza (5.7) models an Order's lifecycle.

Three levels: domain, use case, design exam

The Unified Process has no separate "state model". Instead, any element in any model can have a state machine attached: a domain concept, a use case or a design class (Larman 29.7). A machine for the Sale design class, for example, belongs to the Design Model. The level decides what is modelled and how the events and actions are written, and the exam always asks for the domain level.

LevelWhat is modelledEvents are written asActions / guardsCourse example
Domain (analysis) examA real-world thing, or the system as users see itReal-world occurrences in plain domain language, naming the actor where useful: staff accepts order, obstruction detected, open button pressedReal-world responses: notify customer, charge $20Tony's Pizza Order; credit-card Account (Workshop 6); both exam questions
Use case / system operationThe system as a black box, or the use case treated as an objectThe system operations from the SSD: makeNewSale, enterItem, endSaleUsually noneProcess Sale (Larman Fig. 29.5)
DesignOne software classThe class's public methods, with parameters: insertCard(card), select(p)Calls to (often private) methods: / scanCard(card); guards are boolean expressions over attributesNotation-sheet ATM; sliding Door; JetstarSearch (Workshop 8)
Domain level plain-language events (the exam's level) Submitted staff accepts order UnderPreparation Use case / system level events are the SSD's system operations WaitingForSale makeNewSale EnteringItems Design level events are a class's public methods Waiting for Card insertCard(card) / scanCard(card) Waiting for Pin
Same notation, different vocabulary. The shapes never change; only the wording of events and actions does. Tony's Pizza draws the Order at domain level, "referencing the real-world actors", and then derives a design-level version in which every event becomes a method (5.8).

Kinds of events

Before you can label an arrow you need to recognise the event. Events can be classified in two ways. The Workshop 6 worksheet classifies them by source:

  1. External event: caused by something outside the system, such as a user touch, a button press or a sensor reading.
  2. Internal event: caused by something inside the system, such as an Observer notification or the system detecting a fault.
  3. Temporal event: caused by a date or time, usually checked against a system clock. Examples are "6 months without a transaction" and "no complaint after 1 hour".

UML also classifies events by form, and each form has its own notation on the arrow.

UML event kindNotationMeaning
Call / signal eventname or name(params)A message or signal arrives, e.g. current(co2), insert(coin).
Time event (relative)after(30 s)Fires when the time has passed since the source state was entered.
Time event (absolute)at(23:00)Fires at an absolute time. UML 2 notation; older texts write when(date = …).
Change eventwhen(level > max)Fires at the moment the boolean expression becomes true.
Completion eventno labelFires when the source state finishes its internal activity (5.3).
S T current(co2) Call / signal eventa message or signal arrives, possibly with parameters S T after(30 s) Relative time event30 s after S was entered; the clock restarts on every entry S T at(23:00) Absolute time eventat a clock time (UML 2); older texts write when(date = …) S T when(level > max) Change eventfires the moment the condition becomes true; it is the trigger itself S T (no label) Completion eventfires when S finishes its own activity (see 5.3)
Five ways to trigger a transition. Note that after(…) counts from the moment the source state was entered, which matters when a state is left and re-entered (5.4).

Guard or change event?

These two are easy to confuse. A guard [x > 5] is evaluated only when its trigger event occurs; it never fires anything on its own. A change event when(x > 5) is the trigger, and fires as soon as the condition becomes true. That is why a requirement such as "if the elapsed time ≥ minimum" needs a trigger of its own: a time event, a change event, or a periodic event such as tick with a guard.

value of x time x = 5 x becomes > 5 tick tick tick tick tick [x > 5] ✕ false✕ false fires at the next tick when(x > 5) fires exactly at the crossing (none) [x > 5] ✕ checked once never re-checked, so it never fires
Who triggers the check? Top row: a guard is only looked at when tick arrives, so it fires at the first tick after the crossing. Middle: a change event is its own trigger. Bottom: a guard on a completion transition is checked once, at completion, and not again (5.3).
Check yourselfWhich of these deserves a state machine: (a) a TaxCalculator that computes tax from a price, (b) a microwave oven, (c) a Payment that can be pending, authorised or refunded?

(b) and (c). A microwave is a physical device controlled by software: pressing start means one thing with the door open and another with it closed, so it is state-dependent with complex behaviour (Guideline 1, and device control under Guideline 2). A Payment is a transaction-type business object whose response to, say, a refund request depends on its state. The TaxCalculator responds to every request in the same way, so it is state-independent and a state machine adds nothing.

Check yourselfName the level of each label: (1) enterPin(pin) / validate(), (2) customer makes complaint, (3) endSale.

(1) Design level: a public method with a parameter, and an action that calls a method. (2) Domain level: a real-world occurrence in plain language, naming the actor. (3) Use-case / system-operation level: a system operation taken from the SSD. The exam asks for (2)-style labels.

Check yourselfClassify "6 months without a transaction" by source and by UML form, and write it on an arrow.

By source it is a temporal event (caused by time, checked against a clock). By UML form it is a relative time event, written after(6 months), counting from when the source state was entered. Because "without a transaction" means the time since the last transaction, the source state must be one that is re-entered on each transaction.

Check yourselfA student writes a transition out of Open labelled only [elapsed >= minOpenTime]. Why is this weak, and what are three better options?

With no event, the arrow is a completion transition: its guard is checked once, when Open finishes its activity, and if it is false then it is never re-checked, so the door would wait forever. A guard needs a trigger. Better: a time event after(minOpenTime); a change event when(elapsed >= minOpenTime); or a periodic event with a guard, timer tick [elapsed >= minOpenTime].

In short

Draw state machines for state-dependent objects with complex behaviour, above all in control, device, protocol and telecoms systems. A machine can be attached at the domain, use-case or design level; the exam wants domain level. Events can be calls/signals, after(…), at(…), when(…) or completion, and a guard alone never triggers anything.

5.3

Core Notation: States, Transitions, Start and End exam

Markers in this course read your diagram literally: the revision workshop warns that diagrams "must use correct notation… we will not be guessing or inferring". So the shapes and the label syntax have to be exact. This section covers the everyday symbols; 5.4 and 5.5 add the richer ones.

A word on sources. Larman ch. 29 covers only the basics: states, transitions, events, guards, actions and nested states. The lecture adds the choice pseudostate, and the course notation sheet adds composite states with their own initial states, and initial transitions that carry an action. Internal activities (entry/exit/do), time events, history states and concurrent regions are standard UML 2 notation not in Larman ch. 29. They are included here because exam wording such as "continue running as before the fault" calls for them.

Initial pseudostatefilled dot; no trigger, /action allowed Final statebullseye; the lifecycle ends Idle Staterounded rectangle, domain name Opening entry / start motor State with activitiesentry/, exit/, do/ compartment event [guard] / action Transitionsolid arrow, filled head Dialing digit Self-transitionleaves and re-enters [a][else] Choice pseudostatediamond; one branch by [guards] Printing do / print Idle Completion transitionno event: fires when work is done Active Substate Composite statesubstates + its own initial dot H H* History pseudostatesshallow H, deep H* (inside a composite) Sounding Recording Concurrent regionsdashed split; one state per region Assumption:door starts Closed Noteassumptions, sentence numbers
The complete symbol set. States are always rounded; pseudostates (initial, choice, history) are places the object passes through but never rests in. Get the shapes right first: "wrong shapes" is on the markers' list of common mistakes.

Element by element

ElementHow to draw itRules that go with it
Initial pseudostateSmall filled black circle, one arrow to the first stateEvery machine needs one, and so does every composite entered via its boundary. It "can have actions but should not have a trigger": / initialiseATM() is fine, an event is not. The object never rests there.
Final stateBullseye: a filled circle inside a ringThe lifecycle ends there. You may draw several (Tony's Pizza has one after Completed and one after Cancelled). Many reactive systems have none, because they run forever.
StateRounded rectangle, name inside, optional second compartment for internal activitiesDescriptive problem-domain name; preferably an adjective or participle (Idle, Submitted) or a gerund phrase (WaitingForPayment, Opening).
TransitionSolid arrow from source to target, labelled event [guard] / actionEvery part of the label is optional; a transition with no event is a completion transition.
Self-transitionArrow that leaves and re-enters the same stateIt really exits and re-enters, so exit and entry actions run (5.4).
Choice pseudostateDiamondOne incoming transition carrying the event; two or more outgoing, each with a guard; [else] allowed (5.5).
Composite state (superstate)Large rounded rectangle containing the substates, name at the top or in a tabSubstates inherit the superstate's outgoing transitions; it has its own nested initial pseudostate.
History pseudostateSmall circle containing H (shallow) or H* (deep), inside a compositeRe-entering through it resumes the substate that was active when the composite was last left.
Concurrent regionsComposite split by dashed linesThe object is in one substate of each region at once. Not taught in the course.
NoteDog-eared rectangle, dashed line to an elementUse it for assumptions and sentence references.

The transition string: event [guard] / action exam

The label on an arrow is a tiny sentence with a fixed grammar. The lecture reads it as: when the object is in State A, if the trigger event occurs and the guard is true, then perform the action and move the object to State B.

State A State B trigger-event [guard-condition] / action 1 eventwhat happened 2 [guard]must be true at that moment 3 / actiondone instantly as it fires "In State A, if the event occurs and the guard is true, perform the action and move to State B."
The order never changes: event, then [guard] in square brackets, then / and the action. Larman's Fig. 29.2 is the model: off hook [valid subscriber] / play dial tone.

Four rules apply to the string:

  • The order is fixed: event, then [guard], then / action.
  • If the guard is false, the transition does not fire. If no other transition from that state accepts the event, the event is ignored and the object stays put.
  • Several transitions with the same event leaving one state must have mutually exclusive guards. Otherwise the model is non-deterministic, which is a common mistake.
  • An action is instantaneous and cannot be interrupted. Anything that takes time and can be interrupted by an event is a state (possibly with a do/ activity), not an action.
Waiting for PIN pinEntered pinEntered Waiting for request ✕ whichone fires?
non-deterministic The same event leaves twice with no guards.
Waiting for PIN pinEntered[incorrect] pinEntered[correct] Waiting for request ✓ exactlyone is true
deterministic Exclusive guards: [correct] and [incorrect] can never both hold.

Starting and ending

The initial pseudostate answers "where does the life begin?". Because the object is not yet in any state, nothing can "happen to it" there, so the initial arrow carries no event; the notation sheet allows only an action such as / initialiseATM(). The final state answers "can the life end?". If it can end in more than one way, draw more than one; if the system runs for ever (most controllers), draw none.

✕ Trigger on the initial arrow power on Standby ✓ Only an action is allowed / initialiseATM() Standby Several final states are fine Completed Cancelled
Start and end. An event on the initial arrow is a standard deduction. The Workshop 6 partial solution labels its initial arrow "Onboarded", but prefer the notation-sheet rule. On the right, Tony's Pizza's two endings.

Worked example: the pedestrian crossing light

The lecture's crossing light shows how an English sentence splits into the three parts of the string. The light starts at Red Standing. If the button is pressed when the traffic light is red, it goes to Green Walking and a timer starts. When the timer reaches 30 s it goes to Flashing Red Standing, and at 60 s it returns to Red Standing.

RedStanding GreenWalking FlashingRedStanding button is pressed [traffic light is red] / start timer timer reaches 30 seconds timer reaches 60 seconds / reset timer
Every part of the sentence has a home. "When a timer reaches 30 seconds" is a temporal event; in UML 2 it could be written after(30 s), but the lecture writes it in plain English, which is fine at domain level.
Words in the requirementBecomes
"If the button is pressed"event button is pressed
"when the traffic light is red"guard [traffic light is red]
"and a timer starts"action / start timer
"When a timer reaches 30 seconds"temporal event, no guard, no action

Completion transitions

Sometimes a state ends by itself: a printer finishes printing, a reset completes. A transition with no event leaving a state is a completion transition, and it fires as soon as the state's work is done. For a simple state, that is when its entry actions and do/ activity have finished (immediately, if there are none); for a composite state, it is when its nested final state is reached.

A completion transition may have a guard, but if the guard is false at the moment of completion it is not re-evaluated later, so the object stays in the state (the bottom row of the timeline in 5.2). To mean "leave as soon as X becomes true", use when(X) or a periodic event with a guard. The only other unlabelled arrows are the initial transition and transitions out of a choice (which carry only guards). Any other arrow with no event label is a mistake.

Printing do / print receipt Idle ✓ fires when the do/ activity finishes
completion The state has work of its own that ends.
Draft ? Submitted ✕ what event makes this happen?
flowchart arrow Name the event: customer submits order.
Check yourselfWrite one transition for: "When the alarm is armed, if motion is detected while the door is open, the siren sounds and the alarm goes to Triggered." Which word is the source state?

Source state Armed ("when the alarm is armed" describes where the object is, not a guard). Transition to Triggered labelled motion detected [door open] / sound siren: event first, guard in brackets, action after the slash.

Check yourselfSpot the error: from Monitoring, two arrows are labelled reading [level > 10] and reading [level > 50].

The guards are not mutually exclusive: a reading of 60 satisfies both, so the machine is non-deterministic. Fix: [10 < level <= 50] and [level > 50], or route the event into a choice diamond with exclusive branches.

Check yourselfA student models "charge the customer $20" as a state Charging with an unlabelled arrow out of it. What is wrong, and what should it be?

Charging a fee is instantaneous, not something the object waits in, so it is an action, not a state. The unlabelled arrow is also a give-away. Put / charge $20 on the transition that causes the charge.

In short

States are rounded rectangles; the initial dot has no trigger (only an optional /action); finals are bullseyes, zero or more. Labels read event [guard] / action in that order, guards on the same event must be exclusive, and the only unlabelled arrows are initial, choice branches and deliberate completion transitions.

5.4

Inside a State: entry, exit, do and Internal Transitions

Sometimes the same action belongs on every arrow into a state, or the object keeps doing something for as long as it is in a state. Writing it on every arrow is repetitive and easy to get wrong. UML 2 lets a state carry a second compartment that lists behaviour belonging to the state itself (this is not in Larman ch. 29).

Opening entry / start motor (up) do / raise door exit / stop motor beep [child lock on] / flash LED entry: runs every time the state is entered, by any arrow do: ongoing activity while in the state; interruptible exit: runs every time the state is left, by any arrow internal transition: handles beep without leaving
The second compartment. entry, exit and do are reserved words, so they cannot be used as event names. Any other line, such as beep [child lock on] / flash LED, is an internal transition in the usual event [guard] / action form.
  • entry / a runs on every entry, whichever transition entered the state. Use it when every incoming transition would otherwise carry the same action.
  • exit / a runs on every exit. Use it when every outgoing transition would otherwise carry the same action.
  • do / activity is an ongoing activity that starts after entry. It stops either when an outgoing transition fires or when it finishes on its own, in which case it produces a completion event. Gerund-named states such as FilteringOut often have a do/ activity.
  • An internal transition e [g] / a handles event e without leaving the state, so no exit or entry actions run.
Closed Closing Halted Opening a / start motor b / start motor c / start motor
Repetition. Three arrows say the same thing. Add a fourth way in and it is easy to forget the action.
Closed Closing Halted Opening entry / start motor a b c
Said once. entry / start motor runs whichever arrow is taken. exit/ does the same for actions shared by every arrow out.

Self-transition or internal transition? exam-useful

In both, the object handles an event and ends up in the same state, so they look alike. The difference is whether it actually leaves. A self-transition is a real arrow that goes out of the state and back in; an internal transition is a line inside the state, and the object never leaves. Everything else follows from that.

Dialing entry / start digit timer digit / append digit on each digit: ① exit → ② / append digit → ③ entry the digit timer restarts every time
self-transition Leaves and re-enters: exit, action, entry.
Dialing entry / start digit timer digit / append digit on each digit: only / append digit runs (no exit, no entry) the timer keeps counting from first entry
internal transition Never leaves: action only.
Self-transition (arrow loops back)Internal transition (listed inside the state)
Leaves the state?Yes, then re-entersNo
Exit and entry actions run?Yes (exit, action, entry)No (action only)
do/ activityAborted and restartedContinues
Time events such as after(t)Restart (state re-entered)Keep counting from the original entry
Composite stateRe-enters via the initial substate, so the current substate is lostSubstate unchanged

Here is the worked contrast. Suppose a phone in Dialing has entry / start digit timer and after(10 s) / play error tone leading to Idle. If digit / append digit is a self-transition, each digit re-enters Dialing and restarts the timer, so you get an inter-digit timeout. If it is an internal transition, the 10 s counts from the first entry, so you get a total dialling timeout.

0 s5 s10 s15 s digits pressed ●●●● Self-transition inter-digit timeout 10 s from the last digit timeout at 17 s Internal transition total dialling timeout 10 s from the first entry, digits do not reset it timeout at 10 s
Same diagram, one choice apart. The bars are the running 10 s timer. Restarting it (self-transition) and letting it run (internal transition) give two different products, so choose deliberately.

This is why the garage-door answer (5.10) sets its timer on the incoming transition rather than as an entry action: a "keep waiting" self-loop then does not reset it.

Check yourselfState Open has entry / set timer, and a self-loop timer tick [elapsed < minOpenTime]. What goes wrong?

A self-loop leaves and re-enters Open, so entry / set timer runs again on every tick and the elapsed time is reset each time. The door would never reach minOpenTime: a classic semantic error. Fix it either by making the tick an internal transition (no re-entry) or by setting the timer on the incoming transition (door fully open / set timer), not in entry.

Check yourselfA composite state Active is currently in its substate Talking. Event e is drawn as a self-transition on Active's boundary. Where is the object afterwards? What if e were an internal transition of Active?

As a self-transition, the object leaves Active and re-enters through its initial substate, so Talking is lost and it lands in whatever the nested initial dot points to. As an internal transition, it never leaves, so it stays in Talking.

Check yourselfCan a state have an event called exit, for "the user presses the Exit button"?

Not under that name: entry, exit and do are reserved words in the activity compartment. Call the event something like exit button pressed.

In short

entry/ and exit/ factor out actions shared by every way in or out; do/ is ongoing, interruptible work. A self-transition really leaves (exit, action, entry, timers restart, composite resets to its initial substate); an internal transition does not (action only).

5.5

Choices, Composite States, History and Regions exam

Real requirements branch ("if the PIN is correct… otherwise…"), and they contain sweeping phrases like "at any stage" and "continue as before". Drawn with only plain states and arrows, those turn into a tangle of duplicated arrows. This section gives the four structuring tools that keep a diagram small: the choice pseudostate, composite states, history, and (rarely) concurrent regions. It ends with the exact rule for what happens when an event arrives.

The choice pseudostate exam

A choice pseudostate "realizes a dynamic conditional branch". It evaluates the guards of its outgoing transitions and takes exactly one of them. It is useful when one event can lead to different outcomes: you write the event once, then branch. The two halves of the figure below are equivalent (lecture slide 19).

Two guarded arrows Entering PIN Selecting Transaction Calling Police Entered PIN [PIN correct] / display menu Entered PIN [PIN incorrect] / stun patron With a choice pseudostate Entering PIN Entered PIN Selecting Transaction Calling Police [PIN correct] / display menu [PIN incorrect] / stun patron
Event before the diamond, guards after it. The choice version states the event once. Each outgoing branch carries a guard and, optionally, its own action.

The rules for a choice are these:

  • The event goes on the incoming segment only. Each outgoing segment carries a guard and, optionally, an action.
  • There can be two or more outgoing transitions, for example [bal < 0], [0 <= bal < min] and [min <= bal].
  • [else] is predefined and is taken if no other guard is true. Use it to make the branch exhaustive, because if no guard is true at a choice, the model is ill-formed.
  • The guards should be mutually exclusive.
  • A choice can lead back to the same state it started from. In the notation-sheet ATM, enterPin(pin) leads to a choice whose [Invalid] branch goes back to Waiting for Pin.
Open review [bal < 0] [0 <= bal < min] [else] Overdrawn BelowMinimum InCredit three exclusive, exhaustive branches WaitingForPin enterPin(pin) [Invalid] [Valid] WaitingForServiceSelection
More than two branches, and a loop back. Left: [else] catches everything the other guards miss, so the branch can never get stuck. Right: from the notation-sheet ATM, a wrong PIN sends the machine back where it was.

UML also has a junction, drawn as a small filled dot, which is a static branch. It is not used in this course, so always use the diamond.

Composite states (superstates) exam

A state may contain substates, and each substate inherits the transitions of its superstate (the enclosing state) (Larman 29.4; lecture slide 18). The idea comes from Harel statecharts, and it is the main tool for keeping diagrams small. The telephone from the lecture and Larman shows it: while the phone is Active it moves through several sub-phases, but hanging up ends the call from any of them.

Idle Active off hook [valid subscriber] / play dial tone on hook PlayingDialTone digit Dialing digit complete Connecting connected Talking
One arrow instead of four. on hook leaves from Active's boundary, so it applies in PlayingDialTone, Dialing, Connecting and Talking alike. off hook arrives at the boundary, so the phone starts at Active's own initial state, PlayingDialTone.

Entering and leaving a composite has precise rules. The figure below shows the four kinds of arrow, and the list underneath explains them, together with priority, completion and the order of entry and exit actions.

P Q S A B x R U p q r u 1 2 3 4
Where an arrow touches matters. The boundary means "the composite as a whole"; a substate's edge means "only that substate".
  1. Entering via the boundary. An arrow to the composite's edge (p, or off hook to Active) enters through the nested initial pseudostate, here into A. That is why a composite entered through its boundary must have a nested initial state; as the case study puts it, "even in these sub-states, there always needs to be a sub-state assigned".
  2. Entering a substate directly. An arrow may cross the boundary to a specific substate (q to B), bypassing the nested initial state.
  3. Leaving from the boundary (inherited transition). An arrow from the composite's edge (r, or on hook) applies whichever substate is current. This is how to model "at any stage / at any point / at any time, X happens": one arrow from the superstate instead of one arrow from every state.
  4. Leaving from a specific substate. An arrow from a substate's own edge (u) fires only from that substate. In Tony's Pizza, Delivered → Completed applies to the Delivered substate only, and the case study stresses being particular about which state such an arrow leaves from.
  • Priority. If a substate and its superstate both handle the same event, the substate's (inner) transition wins.
  • Completion of a composite. If a region reaches its nested final state, an unlabelled arrow from the composite's boundary (a completion transition) fires.
  • Entry and exit order. Entering from outside runs the superstate's entry and then the substate's; leaving runs the substate's exit and then the superstate's.
  • Conceptual grouping. Besides saving arrows, a composite groups related states. In the case study the delivery states form a Delivery superstate, because they are really the states of the Delivery concept nested inside Order.

The course notation sheet: the Simple ATM

The notation sheet brings several features together: an initial transition with an action, a composite with its own initial state, design-level events with parameters, two choice pseudostates and a final state. Two of its sentences are worth tracing. Sentence 2 says the ATM "can be disconnected at any time" in standby, which becomes disconnectATM() from Standby to the final state. Sentence 8 says card removal returns the ATM "from being active to being on standby", which becomes releaseCard(card) from the Waiting for Card Removal substate (not the boundary) back to Standby, because removal is only legal at that point.

/ initialiseATM() Standby disconnectATM() Active startService() WaitingForCard insertCard(card) / scanCard(card) WaitingForPin enterPin(pin) [Invalid] [Valid] WaitingForServiceSelection selectService(service) [service == deposit] [service == withdrawal] WaitingForCashDeposit EnterAmountToWithdraw insertCash(amount) /processDeposit() withdrawCash(amount) /processWithdrawal() WaitingForCardRemoval releaseCard(card)
The notation sheet, redrawn. It is a design-level machine (events are methods with parameters, actions are method calls). Notice the initial arrow with an action and no trigger, the composite's own initial dot, choices with an incoming event and guarded branches, and releaseCard(card) leaving from one substate, not from the boundary.

History pseudostates: H and H* exam

History states are not in Larman ch. 29 or the lecture, but they are the exact UML answer to wording such as "once the reset is complete, the filter will immediately continue running as before the fault" (2021 S1 Q5).

The problem is memory. An arrow to a composite's boundary always restarts at the initial substate, which forgets where the object was. A shallow history (H) pseudostate, a circle containing H drawn inside a composite, fixes that: a transition into H re-enters the composite at the direct substate that was active when the composite was last exited. If that substate is itself composite, it is entered through its own initial state.

Cycle Washing washed Rinsing door opened Paused door closed Was Rinsing when paused? It restarts at Washing (the initial substate).
to the boundary "Go back to normal operation": start again.
Cycle Washing washed Rinsing H door opened Paused door closed Was Rinsing when paused? It resumes Rinsing: "continue as before".
to H "Continue as before / resume": pick up where it left off.

Deep history (H*), drawn as a circle containing H*, goes further and restores the last active configuration at every nesting level. If the composite has never been active, there is nothing to remember. For that case you can add a default history transition, an unlabelled arrow from H to a substate; without one, entry falls back to the composite's initial state.

Cycle Washing Heating heated Spraying washed Rinsing H H* shallowdeep Suppose it was in Spraying when Cycle was left. Re-enter via H: remembers only the top level: Washing, then Washing's own initial state, so Heating. Re-enter via H*: restores every level, so Spraying.
Shallow versus deep. H remembers which direct substate was active; H* remembers the whole nested configuration. In the exam, shallow H is all you will need.
The key contrast

"Go back to normal operation / normal monitoring" means an arrow to the boundary (or to the initial state). "Continue as before / resume where it left off" means an arrow to H.

On paper, draw a small circle with H inside, placed inside the composite, and point the "resume" transition at it. (Mermaid, which the study guide uses, has no history pseudostate, so the guide draws it as a state named H.) Flat fallback if you forget H: duplicate the interrupting state, one copy per substate to return to (e.g. ResettingWhileFilteringOut and ResettingWhileAddingIn). Correct, but clumsier.

Concurrent (orthogonal) regions

Sometimes an object has two independent aspects at once. A composite state can be split by dashed lines into regions, and the object is then in one substate of each region simultaneously. Each region has its own initial state, and an event can trigger transitions in several regions at once. Fork and join bars (thick lines) split one transition into several regions or merge them back. This is UML 2 and not taught in the course; use it only if the text clearly describes independent, simultaneous aspects, such as "the alarm sounds while the camera records".

Armed Intruder Alert region 1: the siren region 2: the camera Sounding silence pressed Muted Recording storage full Stopped motion detected reset
Two regions, two current states. On entry the object is in Sounding and Recording at once; silencing the siren does not stop the camera. (An illustration of the notation; the course never asks for it.)

The one place the course material comes close is the Workshop 11 partial solution. Its Zone_Unit frame contains two separate machines, each with its own initial state: one tracks whether the zone is armed (Inactive, Countdown/Beeping, Active), the other whether it is switched On or Off. That is two orthogonal regions in effect, although the solution leaves out the dashed separator. If you ever need the idea, draw the dashed line.

What happens when an event arrives

Putting the notation together, these are the firing rules. They are what you are applying, in your head, whenever you trace a scenario through a diagram.

  1. At any moment the object is in exactly one state (one per region), and through nesting it is also "in" every enclosing superstate.
  2. When an event arrives, look for transitions triggered by it, starting from the innermost current state and moving outwards through the superstates.
  3. Evaluate their guards. At most one should be true. If none is true, or no transition handles the event, the event is ignored.
  4. Fire the transition: run the exit actions (innermost outwards), then the transition action (and any choice branch), then the entry actions (outermost inwards), and then start the do/ activity.
  5. Events are processed one at a time, which is called run-to-completion: the next event is handled only after the current step finishes.
S entry / eSexit / xS A entry / eAexit / xA T entry / eT e / t 1 2 3 4 order: xA → xS → t → eT exits from the inside out, then the action, then entries from the outside in
Leaving a nested state. ① A's exit, ② S's exit, ③ the transition action, ④ T's entry. Entering S from outside would run them the other way round: eS before eA.
Trace it: the telephone, one event at a time
Idle Active off hook [valid subscriber] / play dial tone on hook PlayingDialTone digit Dialing digit complete Connecting connected Talking event just processed (start) off hook, valid subscriber digit digit complete connected digit (ignored) on hook
  1. The life starts at the initial dot, which immediately moves the phone to Idle. The gold outline marks the current state.
  2. off hook arrives and the subscriber is valid, so the guard is true: play the dial tone and enter Active. The arrow ends at Active's boundary, so the phone enters through Active's own initial dot into PlayingDialTone. It is now in PlayingDialTone and (by nesting) in Active.
  3. digit: the innermost state, PlayingDialTone, has a digit transition, so the phone moves to Dialing.
  4. Another digit: Dialing's self-transition fires. The phone leaves and re-enters Dialing (any exit and entry actions would run again).
  5. complete: the number is complete, so the phone moves to Connecting.
  6. connected: the other party answers; the phone is now Talking.
  7. A stray digit while Talking: neither Talking nor Active has a digit transition, so the event is ignored. Nothing moves; this is Larman's "undrawn means ignored" rule.
  8. on hook: Talking has no such arrow, so the search moves outwards to the superstate. Active's boundary has on hook, an inherited transition that works from any substate, so the phone leaves Talking and Active and returns to Idle.
Check yourselfWhere does the event go in a choice construct: on the arrow into the diamond, or on the arrows out of it? And what goes on the arrows out?

The event goes on the incoming segment only. Each outgoing segment carries a guard (and optionally an action). The guards must be mutually exclusive and should be exhaustive, which [else] guarantees.

Check yourselfA requirement says: "At any time while the order is being prepared or delivered, staff may cancel it." There are four preparation and delivery states. How do you draw this with one arrow?

Wrap exactly those four states in a superstate (with its own nested initial state) and draw one staff cancels order / notify customer transition from the superstate's boundary to Cancelled. Each substate inherits it. Check the superstate holds exactly the states the text names and no others.

Check yourselfA machine is in substate B of composite S. Both B and S's boundary have a transition on event e. Which fires?

The inner one, from B. The search for a transition starts at the innermost current state and only moves outwards if nothing there handles the event, so the substate's transition has priority.

Check yourself"After a power cut, the robot goes back to its normal patrol." vs "After a power cut, the robot carries on with whatever task it was doing." Boundary or H?

The first ("goes back to normal") is an arrow to the composite's boundary (or its initial state): it restarts. The second ("carries on with whatever it was doing" = continue as before) is an arrow to a shallow history H inside the composite, which resumes the remembered substate.

Check yourselfLeaving substate A (exit xA) of composite S (exit xS) on e / t into T (entry eT): in what order do the four behaviours run?

xA, xS, t, eT: exits from the innermost outwards, then the transition action, then entries from the outermost inwards.

In short
  • Choice: event in, guarded branches out; exclusive, and exhaustive with [else].
  • Composite: arrow to the boundary enters at the nested initial state; arrow from the boundary works from any substate ("at any stage"); inner transitions win.
  • History: H resumes the last direct substate ("as before"), H* every level; the boundary restarts ("back to normal").
  • Regions (not in the course): dashed split, one state per region at once.
5.6

Modelling Guidelines

Knowing the symbols is half the job. The other half is reading ordinary English requirements and deciding which words become states, which become events, and which become guards or actions. This section collects the course's rules of thumb for that translation, the naming conventions, and the mistakes that cost marks.

Reading requirements: which words become what exam

Exam questions describe behaviour in everyday language, so the first skill is recognising cues. Step 2 of the exam procedure (5.9) is exactly this table applied sentence by sentence.

Cue in the textModel elementExample
"When … is turned on", "starts", "is created", "a new order"Initial pseudostate and the first state"When the vending machine is turned on, it will wait for…"
"waits", "remains", "until", "is pending/active/suspended", a period of timeState"remain in the shutdown state until safe_restart"
"-ing" process that takes time and can be interruptedState (gerund name), optionally with do/"start opening" → Opening; "filtering CO2 out" → FilteringOut
"If/when X is pressed/detected/received/occurs", a named signal (often in italics)Eventcurrent(co2), safe_restart, "obstruction detected"
"if [condition]", "when the level is above…", "if the customer pays by card"Guard […][co2 > max_co2], [pay by card]
One event with several "if… otherwise" outcomesChoice pseudostate with guarded branches, or several transitions with exclusive guards"if the pin is correct… otherwise…"
"and will also…", "a timer will be set", "notify", "charge", "display"Action after / (or entry/ if it happens on every entry)/ set timer, / notify customer
"after N seconds/minutes/months", "timer reaches", "elapsed time"Time event after(N), or a tick event with guards"6 Months", "no complaint after 1 hour"
"At any stage / at any point / at any time, X → Y"Superstate around the states concerned; one transition from its boundaryemergency shutdown, fault, cancel order, out of order
"continue as before / resume"History pseudostate HCO2 filter after reset
"go back to normal operation / monitoring"Transition to the superstate boundary (its initial substate) or to the named statesafe_restart → Monitoring
"goes back to step N"Transition to the state described in sentence Ngarage door: vehicle detected → Opening (step 3)
"is closed / ends / is destroyed / must re-apply as new"Final statecredit card "Close"
Key:special phrasestateeventguardaction When the vending machine is turned on, it will wait for a selection. → initial pseudostate ● → state waitingForSelection If the level rises above max_co2, the filter starts filtering CO2 out until the level reaches max_co2 − upper_threshold. → current(co2) [co2 > max_co2] into state FilteringOut; "until" = an event out: current(co2) [co2 <= …] At any stage, if an emergency is detected, the system performs an emergency shutdown. → superstate around everything; ONE arrow from its boundary: emergency / perform emergency shutdown Once the reset is complete, it immediately continues running as before the fault. → reset complete leads to H inside the Running superstate (resume the old substate)
Annotating sentences. This is what your exam paper should look like after step 2 of the procedure: every cue word marked with what it will become. All four sentences come from the course's examples and past exams.

State or not? The tests

A state is a condition the object can sit in while an event arrives. Most modelling errors come from turning the wrong things into states, so apply these tests to every candidate:

  • Does the object wait here for something? The case study's rule is that whenever the object must wait for a period, it gets a state. AssigningDeliveryStaff is a state because no driver may be free for ten minutes.
  • Does it change what happens next? Adding and editing items in a draft order "doesn't really feel like it's changed the state of the order", so the order stays in Draft, and the edits become a self-transition or internal transition rather than a new state.
  • Instantaneous work is an action, not a state. "Charge $20", "notify the customer", "issue a new card" and "check the PIN" all happen on a transition. A state called CheckingPIN followed by an unlabelled arrow is usually a choice pseudostate in disguise.
  • Something that sounds like a state may be a transition. In the case study, "rejected" first looked like a state. But the text then says the customer edits and resubmits, so rejection is really the transition staff rejects order / add note back to Draft.
  • Split a state if the legal events differ. The case study considered a single ReadyForPickup state for both pickup and delivery orders, but split it, because "customer collects order" is only legal for pickup orders and a shared state would need guards on everything.
  • Name implicit states. The text may never name the period between two events, such as between "starts a new order" and "submits". Invent a sensible domain name (Draft, Collecting), but prefer the requirement's own words when they exist (Submitted, Collected).
Waiting for PIN pinEntered CheckingPIN yes no Waiting for request ✕ an actiondressed as a state
bad Nothing can happen "while checking": it is instantaneous. The unlabelled "yes/no" arrows give it away.
Waiting for PIN pinEntered [correct] [incorrect] Waiting for request ✓ a choice pseudostate
good The check is the choice; the outcomes are guards.
Draft Submitted customer submits Rejected staff rejects customer edits
extra state "Rejected" has nothing to wait for; the order goes straight back to being edited.
Draft Submitted customer submits staff rejects order / add note for customer ✓ rejection is a transition back to Draft
good The case study's own correction: the note is an action on the way back.

Naming conventions

The course is consistent in how it names states but mixes styles for events. Whatever style you use, do not give a state an event-like name (Submit), or an event a state-like name (Submitted used as a trigger). Nouns and adjectives on one side and verbs on the other is what keeps the two apart.

ElementConventionExamples from the course
StateDescriptive problem-domain term in UpperCamelCase or Title Case: an adjective/participle (condition) or a gerund phrase (ongoing activity or waiting)Idle, Active, Pending, Suspended, Submitted, Delivered; WaitingForSale, EnteringItems, WaitingForPayment, AuthorizingPayment, PlayingDialTone, Dialing, Waiting for Pin
Event, domain levelA short phrase naming what happened, often with its actor: noun phrase, past participle or present tenseoff hook, on hook, overdue payment, outstanding bill is paid, staff accepts the order, the button is pressed, timer reaches 30 seconds
Event, design level / system opsThe operation name in lowerCamelCase with parametersmakeNewSale, enterItem, startService(), insertCard(card), enterPin(pin)
Event given in the questionReuse it exactlycurrent(co2), safe_restart
GuardBoolean expression in [ ][valid subscriber], [PIN correct], [bal < 0], [service == deposit], [else]
ActionAfter /: imperative verb phrase or method call/ play dial tone, / notify customer, / scanCard(card), / processDeposit()

Common mistakes and what markers look for exam

The Workshop 6 review slides only present an example, so this list is assembled from the notation-sheet rules, the case-study reasoning, Larman, and the revision workshop's warning that diagrams "must use correct notation… we will not be guessing or inferring" (Workshop 11). The numbers match the badges in the "spot the mistakes" diagram below.

  1. No initial pseudostate. Every machine needs one, and so does every composite entered via its boundary.
  2. A trigger on the initial transition. Only / action is allowed there. (The Workshop 6 partial solution labels it "Onboarded", but prefer the notation-sheet rule.)
  3. States that are really actions or activities, such as Charge Fee, Check PIN or Notify Customer. Make them / actions or choice branches instead.
  4. Unlabelled arrows between ordinary states. Every non-completion transition needs an event.
  5. Missing guards where the text says "if…". In particular, the same event leaving a state twice without exclusive guards is non-deterministic.
  6. Guards written informally, as "Yes/No" with a question in the diamond (as in the Workshop 6 partial solution). In the exam, write proper [condition] guards.
  7. Ignoring "at any stage", or drawing ten separate arrows instead of one superstate transition. Both are weaker than a superstate. Also check that the superstate contains exactly the states the text names: in Tony's Pizza, cancel is legal during preparation and delivery but not in ReadyForPickup.
  8. Using the boundary when the text says "resume as before". That calls for H, or for a separate reset state per mode that returns to that mode, which is what the official 2021 S1 Q5 answer draws. Conversely, using H when the text says "go back to normal monitoring" is wrong.
  9. Dead ends and unreachable states. Every non-final state needs a way out, and every state must be reachable from the initial state.
  10. Drawing a flowchart or activity diagram. States are not process steps, so do not join "states" with unlabelled sequence arrows or use diamonds without guards.
  11. Wrong shapes. States are rounded rectangles, a choice is a diamond, the initial pseudostate is a filled dot and the final state is a bullseye.
  12. Wrong level. The question asks for domain level, so use domain events (obstruction detected) rather than invented method signatures, although names the question gives are fine. The Workshop 11 partial solution shows the design level: its events are the design classes' methods (activate(), switch_zone(true)) and its actions are attribute assignments (/is_active = true). Both official 2021 answers stay at the domain level (fault detected, open button pressed).
  13. Inconsistent names between the text and the diagram. Reuse the question's vocabulary, and state any assumptions in a note.
Idle Check Sensor OK? Yes No Open Alarm Closing timer timer Fault fault fault Maintenance 1 3 4 5 6 7 9 9 11
Spot the mistakes. ① no initial dot; ③ Check Sensor is an action, not a state; ④ an unlabelled arrow between ordinary states; ⑤ timer leaves Open twice with no guards; ⑥ a "yes/no" question diamond (flowchart style, mistake 10 too); ⑦ separate fault arrows instead of one from a superstate; ⑨ Fault is a dead end and Maintenance is unreachable; ⑪ Closing has square corners.
Check yourselfClassify each phrase: (a) "the customer must re-apply as a new customer", (b) "a timer will be set", (c) "if the customer pays by card", (d) "remain in the shutdown state until safe_restart".

(a) Final state ("must re-apply as new" ends this lifecycle). (b) Action / set timer. (c) Guard [pays by card]. (d) A state (Shutdown, "remain") with an event out of it (safe_restart, "until").

Check yourselfA student names a state Notify Customer and an event Delivered. What would you change?

Notify Customer is an instantaneous action, so it should be / notify customer on a transition (mistake 3), not a state. Delivered reads like a state (a participle describing a condition), so as an event it is confusing; name the occurrence instead, e.g. delivery staff delivers order, and keep Delivered for the state it leads to.

Check yourselfThe question gives the signal name current(co2). A student writes CO2 reading received on every arrow instead. Wrong?

Not fatal, but weaker: when the question gives an event name, the convention is to reuse it exactly (mistake 13, inconsistent names). Write current(co2) with guards on the thresholds.

In short

Translate cues: waiting/"-ing" → state, "if/when X happens" → event, "if condition" → guard, "notify/charge/set" → action, "at any stage" → superstate, "as before" → H. A state is somewhere the object waits; instantaneous checks and charges are choices and actions. States are nouns or adjectives, events are what happened, and the 13 mistakes are the markers' checklist.

5.7

Worked Example: Tony's Pizza Order Lifecycle

The course case study models one business object, a pizza Order, at domain level. It is a perfect rehearsal for the exam because it uses nearly every feature: choices, a superstate, a time event and two final states. Read the requirements first, then step through the diagram as it is built.

The requirements (summarised from the case study)

A customer starts a new order and adds or edits its contents until ready to submit. On submission the order is assigned to the restaurant, and customers paying by card get a pending charge. Staff then accept or reject the submitted order; a rejection needs a note, and the customer must edit and resubmit.

An accepted order is prepared, and what happens when it is marked ready depends on the kind of order. For a pickup order, the customer is notified, and collection finalises any card charge and completes the order. A delivery order instead waits for a free driver: assigning the driver notifies the driver, collection notifies the customer, and delivery finalises any card charge.

A delivered order is complete if there is no complaint within an hour, but a complaint must be resolved first. Finally, at any point during preparation or delivery, staff may cancel the order, and the customer is notified.

Building the Order lifecycle, requirement by requirement
Delivery Draft customer adds or edits contents customersubmits order [pays by cash] [pays by card] / place pending charge on card Submitted staff rejects order / add note for customer staff acceptsorder UnderPreparation staff marks order as ready [pickup order]/ notify customer ReadyForPickup customercollects order [paid by cash] [paid by card] / finalise card charge Completed [delivery order] AssigningDeliveryStaff delivery staff assigned /notify delivery staff Collecting delivery staff collects order /notify customer Collected delivery staffdelivers order [paid by cash] [paid by card] / finalise card charge Delivered after(1 hour) customer makes complaint ProcessingComplaint complaint resolved staff cancelsorder/ notify customer staff cancelsorder/ notify customer Cancelled
  1. "A customer starts a new order": the initial pseudostate creates the order in Draft, an implicit state the text never names. Adding or editing contents "doesn't really feel like it's changed the state", so it is a self-transition, not a new state.
  2. "On submission… customers paying by card get a pending charge": one event, customer submits order, with two outcomes that differ only in their action. So the event goes before a choice, and the guards [pays by card] / [pays by cash] after it. Both lead to Submitted.
  3. "Staff then accept or reject": staff accepts order leads to UnderPreparation. Rejection is not a state: the customer edits and resubmits, so it is the transition staff rejects order / add note for customer back to Draft.
  4. "What happens when it is marked ready depends on the kind of order": another choice. A pickup order goes to ReadyForPickup while notifying the customer; collecting it reaches a third choice on how it was paid, finalising any card charge on the way to Completed.
  5. A delivery order enters the Delivery superstate through its boundary, so it starts at the nested initial state in AssigningDeliveryStaff. That is a state because the order must wait: no driver may be free for ten minutes.
  6. Assigning the driver notifies the driver (an action) and leads to Collecting; the driver collecting the order notifies the customer and leads to Collected.
  7. delivery staff delivers order goes through a payment choice (finalise any card charge) into Delivered.
  8. From the Delivered substate only: after(1 hour) completes the order; customer makes complaint leads to ProcessingComplaint, which completes on complaint resolved. No [no complaint] guard is needed: a complaint leaves Delivered, which cancels the timer.
  9. "At any point during preparation or delivery, staff may cancel": one arrow from UnderPreparation and one from the Delivery boundary (covering all four delivery substates) to Cancelled. Note there is no cancel from ReadyForPickup: the text limits cancellation to preparation and delivery.
  10. The lifecycle can end in two ways, so there are two final states, one after Completed and one after Cancelled. The diagram is complete.

Decisions worth copying

  • Choice pseudostates for "if card / if cash". The event is the same in both cases and only the action differs, so the event sits before the diamond and the guards after it.
  • The Delivery superstate groups the delivery sub-lifecycle, so one staff cancels order arrow from its boundary covers "at any point during delivery". The arrows to Completed and ProcessingComplaint, by contrast, leave from the Delivered substate only.
  • after(1 hour) is a temporal event, measured from entering Delivered. No [no complaint] guard is needed, because a complaint makes the order leave Delivered, which cancels the timer.
  • Two final states, because the lifecycle can end in two ways.
  • Cancel is not drawn from ReadyForPickup, because the text limits cancellation to preparation and delivery.
Check yourselfWhy does the case study split ReadyForPickup from the delivery states, instead of one shared "Ready" state?

Because the legal events differ: "customer collects order" is only legal for pickup orders, while delivery orders wait for a driver. A shared state would need guards on everything. Splitting a state when its legal events differ is one of the "state or not" tests.

Check yourselfA new requirement says staff may also cancel an order while it is ReadyForPickup. What is the smallest correct change?

Add one transition staff cancels order / notify customer from ReadyForPickup to Cancelled. (Alternatively, wrap UnderPreparation, ReadyForPickup and Delivery in a new superstate and draw a single cancel arrow from its boundary, replacing the two existing cancel arrows; that is the better answer if the text said "at any stage after acceptance".)

In short

Tony's Pizza shows the whole toolkit at domain level: an implicit first state (Draft), edits as a self-transition, rejection as a transition back, choices for card/cash and pickup/delivery, a Delivery superstate for "cancel at any point during delivery", an after(1 hour) time event from one substate, and two final states.

5.8

From State Machine to Design Model and Code exam-useful

A domain-level machine explains behaviour; at some point it has to become a class that enforces it. The case study's next step does exactly that: states are mapped to enum values, events become methods, and guards are implemented in the logic of each method. Workshop 6 Part 2 and its review slides do the same. Once you know the mapping, you can move between diagram and code in either direction.

The mapping rules

/ init() S1 S2 entry / en() e(p) [g] / a() 1 2 3 4 5 6 Any event not handled in the current state: ignored (Larman) or an exception (Workshop 8). enum State { S1, S2 } private State state; public Ctx() { init(); state = State.S1; } public void e(P p) { if (state == State.S1 && g) { a(); setState(State.S2); } // else: ignored, or throw } private void setState(State next) { state = next; // + en() on entering S2 1 2 3 4 5 6
Every symbol has a home in the code. Matching badges pair a diagram element with its Java counterpart: ① states → enum, ② initial pseudostate → constructor, ③ event → public method, ④ guard → if condition, ⑤ action → private call, ⑥ entry action → the setState helper.
  • The object whose lifecycle is modelled becomes a class, called the context: for example Account, Door, Order or Vending_Machine.
  • The set of states becomes an «enumeration» (such as State) plus a private attribute state : State.
  • Each event becomes a public method, such as overduePayment() or movementDetected().
  • A guard becomes an if condition inside that method, using attributes or parameters.
  • A transition action becomes a call to a (usually private) method inside the branch, made before or after changing state.
  • An entry or exit action becomes a call made in a private setState() / enterX() helper whenever that state is entered or left.
  • The initial pseudostate becomes the constructor, which sets the initial state and runs the initial action.
  • An event that is not legal in the current state can either be ignored (Larman's semantics) or throw an exception. The Workshop 8 JetstarSearch classes "throw an exception… if the method is called in the invalid state".
  • A composite state becomes a check on the superstate, which covers all its substates. Optionally the substates get a separate class or enum: Workshop 6 uses class InDefault with «enumeration» SubState {GracePeriod, PaymentPlanOffered, HealthyDebt, BadDebt}.
  • A time event is raised by a timer or scheduler that calls the event method (for example timeout()).

Worked example: the sliding door (Workshop 6 review)

The review slides' sliding door has five states: doors closed (the initial state, with /initialiseDoor()), doors open, doors closing, maintenance and doors locked. movementDetected takes it from closed or closing to open; timeout (after 15 s) from open to closing; doorFullyClosed from closing to closed; keyOverride from closed to maintenance and reset() back; and lock doors / unlock doors move it between closed and locked.

/ initialiseDoor() Closed Open Closing Maintenance Locked movementDetected() timeout()(after 15 s) movementDetected() doorFullyClosed() keyOverride() reset() lockDoors() unlockDoors()
A design-level machine. Every event is one of Door's public methods; the initial arrow carries the action / initialiseDoor(). movementDetected() appears twice because it is legal in two states, which the code below handles with two case labels.
Door -state : State +movementDetected() : boolean+timeout() : void +keyOverride() : void+reset() : void +lockDoors() : void+unlockDoors() : void +doorFullyClosed() : boolean «enumeration»State OPENCLOSINGCLOSED LOCKEDMAINTENANCE
The design class. States → enum literals; events → public methods; one private state attribute.

Reading across. Each arrow of the machine becomes a few lines inside the method named by its event: check that state is the arrow's source, check the guard, run the action, set the target. Arrows that share an event (both movementDetected() arrows) end up in the same method.

Methods that return boolean report whether a transition fired; void methods silently ignore an illegal event. unlockDoors() shows the strict alternative, throwing an exception instead.

Implementation 1: enum plus conditional logic (the course's approach)

public enum State { OPEN, CLOSING, CLOSED, LOCKED, MAINTENANCE }

public class Door {
    private State state;

    public Door() {                         // initial pseudostate: / initialiseDoor()
        initialiseDoor();
        state = State.CLOSED;
    }

    /** Event. Legal in CLOSED and CLOSING; ignored elsewhere. Returns true if a transition fired. */
    public boolean movementDetected() {
        switch (state) {
            case CLOSED:
            case CLOSING:
                openDoors();                // transition action
                setState(State.OPEN);
                return true;
            default:
                return false;               // event ignored in OPEN, LOCKED, MAINTENANCE
        }
    }

    public void timeout() {                 // time event after(15 s), raised by a timer
        if (state == State.OPEN) setState(State.CLOSING);
    }

    public boolean doorFullyClosed() {
        if (state != State.CLOSING) return false;
        setState(State.CLOSED);
        return true;
    }

    public void keyOverride() { if (state == State.CLOSED) setState(State.MAINTENANCE); }
    public void reset()       { if (state == State.MAINTENANCE) setState(State.CLOSED); }
    public void lockDoors()   { if (state == State.CLOSED) setState(State.LOCKED); }
    public void unlockDoors() {
        if (state != State.LOCKED)          // strict alternative: reject illegal events
            throw new IllegalStateException("unlockDoors() not allowed in " + state);
        setState(State.CLOSED);
    }

    private void setState(State next) {     // one place for exit/entry actions and tracing
        System.out.println(state + " -> " + next);
        state = next;
    }
    private void initialiseDoor() { /* ... */ }
    private void openDoors()      { /* ... */ }
}

Guards and nested states: the Workshop 6 credit-card account

Guards and composite states follow the same pattern. In this fragment of the Workshop 6 account, the guard [available fund > 0] becomes part of an if; the In default composite is one enum value with its own sub-state object; its nested initial state plus choice becomes an enter() method; and the inherited transition from its boundary is a single check that covers every substate.

Suspended Active available funds changed[available fund > 0] In default overdue payment outstanding billis paid [missed payments before]/ charge $20 [else] PaymentPlanOffered GracePeriod
The fragment the code below implements (other substates such as HealthyDebt and BadDebt omitted). The Workshop 6 partial solution writes the branch as a Yes/No question; here it uses proper guards, as the exam requires.
public void availableFundsChanged(double funds) {          // event with parameter
    if (state == State.SUSPENDED && funds > 0) {           // guard [available fund > 0]
        state = State.ACTIVE;
    }
}

public void overduePayment() {                              // Active -> In default
    if (state != State.ACTIVE) return;
    state = State.IN_DEFAULT;
    inDefault.enter(customer.hasMissedPaymentHistory());   // nested initial + choice
}

public void outstandingPaid() {                             // drawn from the In default boundary:
    if (state == State.IN_DEFAULT) {                        // one check covers EVERY substate
        state = State.ACTIVE;                               // (= inherited superstate transition)
    }
}

// in class InDefault
void enter(boolean missedBefore) {
    if (missedBefore) { chargeFee(20); subState = SubState.PAYMENT_PLAN_OFFERED; } // [yes] / charge $20
    else              { subState = SubState.GRACE_PERIOD; }                          // [no]
}

Implementation 2: the GoF State pattern (Larman ch. 37)

When several methods repeat the same switch (state) structure, Larman offers the State pattern as an alternative. It is not part of this course's GoF lectures, but it is the natural object-oriented answer to the same problem.

State pattern

Problem: an object's behaviour depends on its state, and its methods contain case logic reflecting conditional state-dependent actions. Is there an alternative to conditional logic?

Solution: create a class per state, all implementing a common interface. The context delegates state-dependent operations to its current state object, and always points to the object for its current state.

Every event method opens with the same question, "which state am I in?", answered by a switch or a chain of ifs (the code above). Adding a state means editing every event method, and it is easy to miss a case.

public boolean movementDetected() {
    switch (state) {
        case CLOSED:
        case CLOSING: openDoors(); setState(State.OPEN); return true;
        default:      return false;
    }
}
public void timeout() {
    if (state == State.OPEN) setState(State.CLOSING);
}
Door -state : DoorState +movementDetected()+timeout() ~setState(s : DoorState)~openDoors() DoorState movementDetected(d : Door)timeout(d : Door) state1 ClosedStatemovementDetected(d) OpenStatetimeout(d) ClosingStatemovementDetected(d) Door delegates every event: state.movementDetected(this) DoorState's default methods do nothing = the event is ignored.
One class per state. Blue: the context. Violet: the abstract state (italic name). Green: one concrete class per state, overriding only the events that do something in that state.
abstract class DoorState {                       // default = event ignored in this state
    void movementDetected(Door d) { }
    void timeout(Door d) { }
}
class ClosedState extends DoorState {
    @Override void movementDetected(Door d) { d.openDoors(); d.setState(new OpenState()); }
}
class OpenState extends DoorState {
    @Override void timeout(Door d) { d.setState(new ClosingState()); }
}
class ClosingState extends DoorState {
    @Override void movementDetected(Door d) { d.openDoors(); d.setState(new OpenState()); }
}
public class Door {                              // context
    private DoorState state = new ClosedState();
    public void movementDetected() { state.movementDetected(this); }
    public void timeout()          { state.timeout(this); }
    void setState(DoorState s)     { state = s; }
    void openDoors()               { /* ... */ }
}
Enum + switch/ifState pattern
SizeSmall, all logic in one classOne class per state
Adding a stateEdit every event method (risk of missing a case)Add a class; only affected transitions change
Readability for many states/eventsPoor, with repeated case logicGood: each state's behaviour is in one place (High Cohesion, Polymorphism; see Part IV)
Typical useWorkshop 6, exam-sized problemsComplex, evolving state-dependent objects, e.g. Larman's PersistentObject (New / OldClean / OldDirty / OldDelete / Deleted)

Larman notes that the state objects have no attributes, so a single shared instance of each (a Singleton) is enough; there is no need to create a new state object on every transition as the sketch above does.

Use-case (system-operation) state machines in design

A machine at the use-case level shows the legal order of system operations. Larman's Process Sale machine is the standard example.

WaitingForSale makeNewSale EnteringItems enterItem endSale WaitingForPayment makeCashPayment makeCreditPayment makeCheckPayment AuthorizingPayment authorized
Legal sequences of system operations (Larman Fig. 29.5). Events are the SSD's system operations; there are no actions. Any SSD for Process Sale must be a path through this machine.

In design, the controller (see Part IV) or a session object can enforce this order, for example by rejecting makePayment before endSale. This is the "session object… to disallow out-of-order operations" alternative that Larman mentions in ch. 11. A system state machine also works as a consistency check for SSDs (Part II), because every SSD scenario must be a path through it; the vending machine in 5.10 shows this.

Check yourselfIn the enum-and-switch Door, how is the composite-style idea "this event is legal in two states" expressed, and what happens if movementDetected() is called while LOCKED?

Two case labels (CLOSED and CLOSING) fall through to the same branch, which is the code form of two arrows with the same event and target. In LOCKED the default branch returns false: the event is ignored, matching Larman's semantics for an event that is not drawn.

Check yourselfTranslate into Java: from WaitingForCoin, insert(c) [value(c) >= price(selected)] / dispense(selected) leads to dispensingProduct.
public void insert(Coin c) {
    if (state == State.WAITING_FOR_COIN && value(c) >= price(selected)) {
        dispense(selected);                 // action
        state = State.DISPENSING_PRODUCT;   // target
    }
}

Event → public method with the parameter; source state and guard → the if; action → private call; target → assignment.

Check yourselfYour team's Order class has eight states and twelve event methods, each starting with a switch (state). A ninth state is coming. What does Larman suggest, and why?

The State pattern: one class per state behind a common interface, with Order delegating each event to its current state object. Adding a state then means adding one class and changing only the affected transitions, instead of editing all twelve switches (and risking a missed case). Each state's behaviour sits in one cohesive place, using Polymorphism instead of conditionals.

In short

Context class; states → enum + state field; events → public methods; guards → if; actions → private calls; entry/exit → a setState helper; initial → constructor; illegal events → ignore or throw; a composite → one check on the superstate. When many methods repeat the same switch, the State pattern replaces it with one class per state.

5.9

The Exam Procedure: a Domain-Level Machine from Numbered Sentences exam

The exam question gives you about six or seven numbered sentences describing a device or system, and asks for a domain-level state machine diagram worth 15 marks. Without a method it is easy to miss a sentence or to draw a flowchart. Budget about 15 minutes and work through these ten steps in order.

  1. Identify the subject. Find the one object or system whose lifecycle is described ("the CO2 filter system", "the garage door"), and write it as the diagram title.
  2. Annotate each sentence using the cue table (5.6). Circle the states (waiting, ongoing activity, conditions), underline the events (often italic in the question), bracket the guards ("if…") and mark the actions ("will set / notify / charge"). Flag the special phrases: "at any stage" means a superstate, "as before / resume" means H, "until" means an event out of a waiting state, "go back to step N" means a transition to that state, and time phrases mean time events.
  3. Draw the initial pseudostate and the first state described ("when turned on, it will wait for…"). No event on the initial arrow, although an / action is allowed.
  4. Lay out the main flow sentence by sentence. Add each new state, then its outgoing transitions with event [guard] / action, reusing the names given in the question.
  5. Handle branches. For one event with several outcomes, use a choice diamond or several arrows with mutually exclusive, exhaustive guards ([else] helps).
  6. Handle timing. Use after(t), or, when the text says the system "monitors" elapsed time, a periodic event (timer tick) with guards.
  7. Handle "at any stage" events. Draw a superstate around exactly the states where the event can occur, give it a nested initial state, and draw one transition from its boundary to the exceptional state (Fault, Shutdown, Out of Order). For the way back, "go back to normal operation" means an arrow to the boundary, while "continue as before" means an arrow to an H inside it.
  8. Add the final state only if the lifecycle can end ("closed", "disconnected", "cancelled"). Control systems usually have none.
  9. Check the diagram. Every sentence covered (write sentence numbers next to elements: markers like traceability); every state reachable and with a way out unless final; no unlabelled arrows except the initial one, choice branches and deliberate completion transitions; correct shapes; no states that are really actions.
  10. Write assumptions in a note, such as "assumed the door starts Closed" or "assumed the door reports fully closed". The course explicitly allows assumptions that are consistent, reasonable and listed.

Here is the procedure applied to 2021 S2 Q8, the garage door, one sentence at a time. The sentences are:

1. The system safely operates a door on a home garage.
2. If the open button is pressed, the door starts opening.
3. While opening, if an obstruction is detected the door halts until the obstruction is removed.
4. Once fully open, a timer is set and the door waits.
5. The door monitors the elapsed time since it opened. If the elapsed time is less than the
   minimum open time, it keeps waiting while open. If it is greater than or equal, the door
   starts closing.
6. While closing, it may detect a vehicle, in which case it starts opening again (back to step 3).
7. At any stage, if a fault is detected, the door stops and enters a fault state until the
   system is restored, then goes back to normal operation.
Garage door, sentence by sentence
Garage door system Normal Operation Closed open buttonpressed Opening 2 obstruction detected /stop door Halted obstruction removed 3 door fully open /set timer Open (waiting) 4 timer tick [elapsed < minOpenTime] / keep waiting timer tick [elapsed >= minOpenTime] Closing 5 vehicle detected door fully closed 6 fault detected / stop door system restored Fault 7 Assumptions door starts Closed; door reports "fully closed" (not in text); badges = sentence no.
  1. Steps 1–2. Sentence 1 names the subject, "the garage door", so it becomes the title; it adds no element. Read all seven sentences and annotate them before drawing anything: note "at any stage" in sentence 7 (superstate), "back to step 3" in sentence 6 (a transition to Opening), and "monitors the elapsed time" in sentence 5 (a periodic event).
  2. Sentence 2 (steps 3–4). The text never says where the door starts, so assume Closed (and note it). Draw the initial dot → Closed, then open button pressed → Opening, a gerund state because opening takes time and can be interrupted.
  3. Sentence 3. "Halts until the obstruction is removed": a waiting state Halted, entered on obstruction detected / stop door and left on obstruction removed back to Opening. "Until" always signals an event out of a waiting state.
  4. Sentence 4. "Once fully open, a timer is set and the door waits": event door fully open, action / set timer, target Open (waiting). The timer is set on the transition, not as an entry/ action, so that a "keep waiting" loop cannot reset it.
  5. Sentence 5 (step 6, timing). "Monitors the elapsed time" needs a trigger, so use a periodic timer tick with exclusive guards: the internal transition timer tick [elapsed < minOpenTime] / keep waiting makes "continue waiting" explicit, and timer tick [elapsed >= minOpenTime] goes to Closing.
  6. Sentence 6. "Back to step 3" means a transition to the state that sentence 3 describes: vehicle detected → Opening. The text never says how closing ends, so assume door fully closed → Closed, completing the cycle (the official answer makes the same assumption).
  7. Sentence 7 (step 7). "At any stage" means a superstate Normal Operation around all five states, with its own initial state (Closed) and an outer initial dot. One arrow fault detected / stop door leaves its boundary for Fault; system restored returns to the boundary, because the text says "back to normal operation", not "as before": no history. No final state (step 8): the door runs indefinitely.
  8. Steps 9–10. Check: every sentence has a badge; every state is reachable and has a way out; the only unlabelled arrows are the initial ones. Then write the assumptions in a note. Done in well under 15 minutes.
Check yourselfA new sentence 8 says: "If the power fails at any time, the door freezes, and when power returns it carries on exactly as it was." What do you add?

A state Frozen outside Normal Operation, entered by power fails from the Normal Operation boundary ("at any time"). The way back is power returns to a shallow history H inside Normal Operation, because "carries on exactly as it was" means continue as before, not restart at Closed.

Check yourselfWhy must you not add obstruction handling while Closing, or a final state, to the garage door?

Neither is in the text. Inventing behaviour costs time and can conflict with the marking scheme; at most mention them in an assumption note. The door runs indefinitely, so there is no final state.

In short

Title → annotate cues → initial + first state → main flow with event [guard] / action → branches → timing → superstate for "any stage" (H only for "as before") → final state only if it ends → check coverage, reachability and labels → note assumptions.

5.10

Worked Past-Exam Answers exam

Two past questions asked for a domain-level state machine: 2021 S1 Q5 (the Mars CO2 filter) and 2021 S2 Q8 (the garage door). For each, you get the guide's model answer, why it earns the marks, and the official answer (released 26/27 Oct) redrawn and compared. A third question, 2021 S1 Q3, hides a state machine inside a class and links it to an SSD.

2021 S1 Q5: the Mars CO2 filtering system (15 marks)

1. The system safely maintains the CO2 level in a Mars dwelling.
2. It monitors regular updates on the current level: current(co2).
3. If the level rises above max_co2, the filter starts filtering CO2 out until the level
   reaches max_co2 – upper_threshold.
4. If the level drops below min_co2, the filter starts adding CO2 in until the level
   reaches min_co2 + lower_threshold.
5. While running, the filter may detect a fault. It then resets, and once the reset is
   complete it immediately continues running as before the fault.
6. At any stage, if an emergency is detected, the system performs an emergency shutdown.
   It stays shut down until the safe_restart signal, then goes back to normal monitoring.
CO2 filter: building the model answer
CO2 filtering system Operational (normal operation) Running Monitoring FilteringOut do / filter CO2 out current(co2) [co2 > max_co2] current(co2)[co2 <= max_co2 − upper_threshold] AddingIn do / add CO2 in current(co2) [co2 < min_co2] current(co2)[co2 >= min_co2 + lower_threshold] H Resetting fault detected reset complete emergency / perform emergency shutdown safe_restart Shutdown H = shallow history (a circle with H). Resumes FilteringOut or AddingIn, whichever was active at the fault. No final state: it runs indefinitely.
  1. Sentence 1 is context only: it names the subject, "the system" (the CO2 filter), which becomes the title. Annotate first: current(co2), safe_restart are given event names; "until" twice; "while running"; "continues running as before"; "at any stage"; "back to normal monitoring".
  2. Sentence 2 gives the state Monitoring, where the system starts. Its event current(co2) is the only sensor event, so every threshold in the text will become a guard on it.
  3. Sentence 3 gives FilteringOut (a gerund state with do / filter CO2 out). It is entered on current(co2) [co2 > max_co2] and, because of "until", left on current(co2) [co2 <= max_co2 − upper_threshold] back to Monitoring.
  4. Sentence 4 is the mirror image: AddingIn (do / add CO2 in), entered on [co2 < min_co2] and left on [co2 >= min_co2 + lower_threshold].
  5. Sentence 5. "While the filter is running" covers both filtering states, so group them in a superstate Running. fault detected leaves Running's boundary for Resetting, and reset complete goes to H inside Running: "continue running as before" is shallow history, which resumes FilteringOut or AddingIn, whichever was active.
  6. Sentence 6. "At any stage" wraps everything except the shutdown in a superstate Operational (with its own initial state, Monitoring, and an outer initial dot). emergency / perform emergency shutdown leaves its boundary for Shutdown; safe_restart returns to the boundary, entering at Monitoring. The text says "normal monitoring", so there is no history here.
  7. Check and note. Every implied state is present (Monitoring, FilteringOut, AddingIn, Resetting, Shutdown); the given names are reused; there is no final state because the system runs indefinitely. A note explains the H symbol.
Why this earns the marks
  • Every state the text implies is present: Monitoring, FilteringOut, AddingIn, Resetting and Shutdown.
  • The given event names current(co2) and safe_restart are reused, and the thresholds are guards with exact expressions.
  • A superstate handles "at any stage", and that includes time spent in Resetting, because Resetting is inside Operational.
  • History handles "continue as before".
  • The two return paths are deliberately different: history after a fault, but the initial state (Monitoring) after an emergency.

Notes and acceptable variations

  • Readings inside the normal band (min_co2 <= co2 <= max_co2) while in Monitoring, or above the stop threshold while in FilteringOut, need no arrow, because undrawn events are ignored.
  • You may name domain events instead, such as CO2 too high, but using the given current(co2) with guards is closer to the text.
  • The filter starting and stopping can be shown as actions instead of do/ activities: current(co2) [co2 > max_co2] / start filter and … / stop filter.
  • Without H, a flat alternative is two reset states (ResettingFromFilteringOut → FilteringOut, ResettingFromAddingIn → AddingIn). This is exactly what the official answer draws (below), so it is fully acceptable; H is the more compact way to say the same thing. A single Resetting state that returns to Monitoring or to the Running boundary, however, is wrong for sentence 5.
Trace it: fault versus emergency
Operational (normal operation) Running Monitoring FilteringOut do / filter CO2 out current(co2) [co2 > max_co2] current(co2)[co2 <= max_co2 − upper_threshold] AddingIn do / add CO2 in current(co2) [co2 < min_co2] current(co2)[co2 >= min_co2 + lower_threshold] H Resetting fault detected reset complete emergency / perform emergency shutdown safe_restart Shutdown event just processed (start) current(co2), co2 in range current(co2), co2 > max_co2 fault detected reset complete emergency safe_restart
  1. Start: the outer initial dot enters Operational at its boundary, so its nested initial dot puts the system in Monitoring.
  2. A reading inside the normal band arrives. Both guards on current(co2) leaving Monitoring are false, so the event is ignored; the system stays in Monitoring. No arrow needs to be drawn for this.
  3. A reading above max_co2: the guard [co2 > max_co2] is true, so the system moves to FilteringOut, inside Running (and Operational).
  4. fault detected: FilteringOut has no such arrow, so the search moves outwards; Running's boundary has one. The system leaves Running for Resetting, and Running remembers that FilteringOut was its last active substate.
  5. reset complete leads to H, which resumes the remembered substate: back to FilteringOut, "as before the fault". An arrow to Running's boundary would instead have needed an initial state, and would have lost which mode it was in.
  6. emergency: no inner state handles it, but Operational's boundary does, so from wherever the system is (even Resetting) it performs the shutdown and goes to Shutdown.
  7. safe_restart returns to Operational's boundary, so the system enters through the initial state into Monitoring, not FilteringOut: "back to normal monitoring" restarts, unlike the fault path.

The official answer (released 26/27 Oct)

The official answer reaches the same behaviour by a flatter route. Everything except the shutdown sits in a superstate Normal Operation. Inside it, monitoring takes current(co2) into a choice diamond with two guarded branches that carry start actions. The two filtering states return to monitoring with stop actions, and each filtering state has its own reset state that leads back to the state it came from. Here it is redrawn.

Normal Operation monitoring current(co2) [co_2 > max_co2] /start filtering out [co_2 < min_co2] /start adding in Filtering CO_2 out Adding CO_2 In current(co2) [co_2 <= max_co2 − upper_threshold] / stop filtering current(co2) [co_2 >= min_co2 + lower_threshold] / stop adding Resetting (out) Resetting (in) fault detected /start reset reset complete /start filtering out fault detected /start reset reset complete /start adding in emergency detected / shut down pump safe restart Emergency shutdown missinginitial
The official answer, redrawn. Red dashed circles mark where the official answer draws no initial pseudostate (outside and inside Normal Operation). Do not copy that: a missing initial state is a standard deduction, so draw both.

Compared with the guide's diagram, the official answer agrees on the states, the guards, the superstate for "at any stage", and the return to normal operation (not history) after a safe restart. Its differences are all acceptable variations listed above: a choice pseudostate instead of two guarded arrows, actions on the transitions (start filtering out, stop adding) instead of do/ activities, and two reset states instead of H. What it shows markers reward is the guarded current(co2) event with the exact threshold expressions, a return path to the right mode after a fault, and actions that say what the system does.

2021 S2 Q8: the garage door system (15 marks)

The full model answer is the final picture of the 5.9 stepper (press Show all). In summary: initial state Closed (an assumption); open button pressed → Opening; obstruction detected / stop door → Halted and obstruction removed back; door fully open / set timer → Open; a periodic timer tick with guards for sentence 5; vehicle detected → Opening and the assumed door fully closed → Closed; and a superstate NormalOperation with fault detected / stop door → Fault and system restored back to the boundary (no history: "back to normal operation", not "as before").

Points to explain in the answer (as a note)
  • Waiting with guards. The internal transition timer tick [elapsed < minOpenTime] makes "continue waiting" explicit. A self-transition would also be fine, because the timer is set on the incoming door fully open transition, so re-entering Open does not reset it. Had you written entry / set timer inside Open, though, a self-loop would reset the timer on every tick: a classic semantic error.
  • Compact alternatives. after(minOpenTime) from Open to Closing, a choice diamond after timer tick, or the change event when(elapsed >= minOpenTime). All are acceptable if used consistently. A guard-only arrow [elapsed >= minOpenTime] with no event is weak, because a completion transition's guard is evaluated only once.
  • Restore target. "Go back to normal operation" sends the door to the boundary, and so to Closed. If you assume the door must first reach a known position, you could add a choice on restore ([door closed] → Closed, [else] → Closing), but state that assumption explicitly. Compare 2021 S1 Q5, where "as before" demands H.
  • Do not add obstruction handling during Closing, or a final state. Neither is in the text; at most mention them in an assumption note.

The official answer (released 26/27 Oct)

Normal Operation Garage Door Closed open buttonpressed Opening Door obstruction detected obstruction removed Halted set timer reads like an event; clearer:door fully open / set timer Waiting While Door Open time elapsed [time < minOpenTime] [time >= minOpenTime] Closing Door door fully closed vehicle detected fault detected system restored Fault State
Almost state for state the same as the model answer. It uses the choice-diamond variant for sentence 5 (with a loop back for "continue waiting"), assumes the unstated door fully closed event, and draws both initial pseudostates. The one weakness (gold): the arrow from Opening Door is labelled only set timer, which reads as an event.

Three points stand out. First, the official answer uses the choice-diamond variant for sentence 5, one of the compact alternatives above. Second, it also assumes the unstated door fully closed event, so that assumption is expected, not a risk. Third, it draws both initial pseudostates, the outer one and the one inside the superstate, which is the complete form. The guide's version is just as good, and in one respect clearer: door fully open / set timer names the event and the action separately.

2021 S1 Q3: the vending machine (a machine hidden in a class)

Q3 itself asks for an SSD, but the given class Vending_Machine defines exactly the states a state machine needs, and its operations supply everything else. This one is at the system/design level: events are the class's methods.

  • Its attribute is state : {waitingForSelection, waitingForCoin, refundingCoin, dispensingProduct, outOfOrder}.
  • Its public operations, which become the events, are select(Product), insert(Coin), cancel(), refundingComplete(), dispensingComplete() and reset().
  • Its private helpers, which supply the guards and actions, are available(Product): boolean, price(Product): int, value(Coin): int, display(Product), refundCoin(), dispense(Product) and error().
1. When turned on, it waits for a selection.
2. It displays the selected product and waits for a coin.
3. Low-valued coins are returned; high-valued coins are accepted (no change).
4. Once paid, it dispenses.
5. While waiting for payment the customer may cancel, and the machine is ready for another purchase.
6. At any stage an error puts it Out of Order until a technician fixes it and presses reset.
inService waitingForSelection waitingForCoin select(p) [available(p)] / display(p) cancel() insert(c) [value(c) < price(selected)] / refundCoin() refundingCoin refundingComplete() insert(c) [value(c) >= price(selected)] / dispense(selected) dispensingProduct dispensingComplete() outOfOrder error() reset()
The guide's derivation from the class. States = the enum literals (inService is a modelling superstate for sentence 6, not an enum value); events = public operations; guards = private queries (available, value, price); actions = private commands (display, refundCoin, dispense).
  • error() is private, which makes it an internal event that the machine detects itself.
  • No cancel() refund action is needed, because a coin is only accepted when it pays for the product.
  • select(p) [not available(p)] is ignored. Optionally, show it as an internal transition with a "sold out" display.

The SSD link

The Q3 scenario is "error after selecting chips, technician fixes it, purchase completes with a $2 coin". On this machine reset() returns to waitingForSelection (via inService's initial state), so after the reset the customer must call select(chips) again before insert($2). In other words, the state machine tells you which messages the SSD must contain. The official answer to Q3 confirms that re-selection; since that answer is an SSD only, the state machine above remains the guide's own derivation.

:Customer :Technician :Vending_Machine select(chips) error() reset() select(chips) again! insert($2) state afterwards waitingForCoin outOfOrder waitingForSelection waitingForCoin dispensingProduct
The machine dictates the messages. Each message must be legal in the state the previous one left behind. After reset() the machine is waiting for a selection, so the SSD needs a second select(chips) (gold) before the coin. (Returns omitted for space.)
Check yourselfIn the CO2 answer, why does fault detected leave from Running's boundary, not from Operational's?

Sentence 5 says "while running, the filter may detect a fault". Running contains exactly the two filtering states, so faults are only handled there; a fault while merely Monitoring is not described. Drawing it from Operational would wrongly allow faults in Monitoring (and in Resetting). Always make the superstate contain exactly the states the text names.

Check yourselfA student draws a single Resetting state whose reset complete arrow returns to Running's boundary. What mark do they lose, and what are the two correct fixes?

It is wrong for sentence 5: entering the boundary needs an initial state and forgets which mode the filter was in, so it cannot "continue running as before". Fix 1: point reset complete at a shallow history H inside Running. Fix 2 (the official answer's route): two reset states, one per filtering mode, each returning to the mode it came from.

Check yourselfWhy does safe_restart go to Operational's boundary rather than to an H?

Sentence 6 says the system "goes back to normal monitoring": a restart, not a resume. An arrow to the boundary enters through the initial state into Monitoring. Using H here would be mistake 8 in reverse.

Check yourselfOn the vending machine, the customer inserts a $1 coin for a $2 product. Trace the states.

From waitingForCoin, insert(c) with [value(c) < price(selected)] true: action refundCoin(), move to refundingCoin. When refundingComplete() arrives, back to waitingForCoin, still waiting for a high-valued coin. The product is never dispensed until a coin of enough value arrives (no change is given).

In short

CO2: Monitoring with current(co2) + threshold guards; Running superstate with H for "as before"; Operational superstate for "any stage"; safe_restart to the boundary. Garage: Closed → Opening ⇄ Halted → Open (timer tick guards) → Closing; NormalOperation superstate, restore to the boundary. Both official answers agree in substance; copy their guards and actions, not the CO2 answer's missing initial dot. Vending: states from the enum, events from public methods, and the machine decides the SSD's messages.

5.11

One-Page Summary for Your Notes Sheet

You may bring two double-sided A4 pages into the exam. This is the state machine page, condensed from the whole Part; each card links back to where it is explained.

Definitions

States, events, transitions

A state is the condition between events; an event is a noteworthy occurrence; a transition moves the object from source to target when the event occurs. 5.1
Use it for

State-dependent objects

Devices, controllers, protocols, UI flow, business objects (orders), legal sequences of system operations. Rarely for business information system classes. 5.2
Levels

Domain, use case, design

Real-world events; SSD system operations; class methods. No separate UP "state model". The exam wants domain level. 5.2
Label

event [guard] / action

Guards on the same event must be exclusive; an undrawn event is ignored. 5.3
Shapes

Dot, bullseye, rounded box

Initial: filled dot (no trigger, /action allowed). Final: bullseye. State: rounded rectangle. Choice: diamond with [guards] and [else]. History: (H) or (H*). 5.3
Inside a state

entry/, exit/, do/

Internal transitions e[g]/a run no exit or entry; a self-transition re-runs exit/entry and restarts timers. 5.4
Time

after, at, when

after(t) is relative to state entry, at(t) absolute, when(cond) a change event. A guard is checked only when its event occurs. 5.2
Completion

No event

Fires when the state's activity or nested final state completes; its guard is checked once only. 5.3
Superstate

"At any stage"

Substates inherit its transitions. Arrow to the boundary enters at the nested initial state; arrow from the boundary applies in any substate. Inner beats outer. 5.5
History

"As before" = H

"Resume as before" means H; "back to normal operation" means the boundary or initial state. 5.5
Code

Enum + methods

States → enum; events → public methods; guards → if; actions → private calls; illegal event → ignore or throw. The GoF State pattern replaces repeated switches. 5.8
Exam recipe

Ten steps

Title, annotate, initial + main flow, guards and choices, time events, superstate for "any stage" (+ H if "as before"), final state?, check coverage/reachability/labels, note assumptions. 5.9
In short

Draw one object's life with the right shapes and event [guard] / action labels; use choices for branching, a superstate for "at any stage", H for "as before" and the boundary for "back to normal". In the exam, work sentence by sentence, reuse the question's names, number your elements, and write your assumptions in a note.