Memra

State diagrams: events, guards and actions

◈ 5 cards

Passive state versus active state, the event that triggers a transition, the guard that permits it and the action that accompanies it — the life history of one object.

Behavioural modelling, and where events come from

A behavioural model indicates how the software will respond to internal or external events. It is built in five steps, and the ordering matters: evaluate all the use cases until you understand the sequences of interaction; identify the events that drive those sequences and work out which objects they belong to; produce a sequence for each use case; build a state diagram for the system and for the classes that need one; and review the whole model for accuracy and consistency against the use cases it came from.

Step two is where the technique is. An event occurs whenever the system and an actor exchange information — and the event is the fact of the exchange, not the information exchanged. You find events by reading the use case narrative and marking every point of exchange, then asking three questions of each: which actor is involved, what information passes, and what conditions or constraints apply. Some events change the flow of control and some do not, which is a useful filter: in BorrowBox, token scanned moves nothing on its own, but token verified determines everything that follows. Once identified, events are allocated to objects — an object either generates an event or recognises one that happened elsewhere.

Passive state and active state

Behavioural modelling considers two characterisations of state: the state of each individual class as the system runs, and the state of the system as a whole as seen from outside. For a class, the book separates two aspects that students routinely merge.

The passive state of an object is simply the current values assigned to its attributes. A ToolCopy whose conditionGrade is B, whose dueDate is next Tuesday and whose holdExpiry has already passed is in one passive state; change any attribute and it is in another. The active state is the object's status as it undergoes a continuing transformation or processing — Reserved, CheckedOut, InInspection. Nothing moves an object out of an active state by itself: something has to happen to it, and that something is an event (also called a trigger). A UML state diagram draws the active states as nodes and the events as the transitions between them, so it is the life history of one object.

Event, guard, action — the full transition label

A transition can carry more than the event that triggers it. A guard is a condition hung on the transition: when the event arrives the guard is evaluated, and unless it comes back true the transition does not fire; an action occurs concurrently with the transition or because of it, and generally invokes one or more of the object's own operations — its responsibilities.

The sentence that earns marks is this: the guard usually depends on the object's attribute values, which means the guard is where the passive state re-enters the active model. The two characterisations of state are not two unrelated ideas; the active state model is a graph over statuses, and the guards are the places where that graph consults the attributes. Say it in an exam answer and you have shown you understand why the book bothers to define both. A fully labelled transition reads event [guard] / action — for example collect [hold not expired] / logCollection().

Worked example — the BorrowBox ToolCopy lifecycle

Take one physical drill, tracked as a ToolCopy. It begins Available. A member reserves it: reserve [copy in stock] / placeHold() moves it to Reserved. From there, two things can happen. If the member turns up in time, collect [hold not expired] / logCollection() takes it to CheckedOut. If they do not, holdExpires takes it straight back to Available — and notice that this transition has no actor at all, which is why every state diagram needs a scan for timeouts, not just for user actions.

Once CheckedOut, dueDatePassed [not returned] / raiseLateFee() moves it to Overdue. From either CheckedOut or Overdue, returned moves it to InInspection, where the librarian's grade decides the ending: graded [grade in A,B] / reshelve() returns it to Available, while graded [grade = unsafe] / archive() moves it to Retired, a terminal state with no outgoing transitions. Six active states, seven transitions, and three guards that all read attributes: holdExpiry, dueDate, conditionGrade. The passive state is what the guards consult; the active state is what the diagram draws.

ToolCopy — active statesreserveexpirescollectduereturnedreturnedgrade A/BunsafeAvailablestartReservedCheckedOutOverdueInspectionRetiredterminalGuards read the copy attributes: holdExpiry, dueDate, grade.
The ToolCopy life history: Available, Reserved, CheckedOut, Overdue, InInspection, Retired. Each arrow is an event; the full UML label would read event [guard] / action, so the Reserved to CheckedOut arrow is collect [hold not expired] / logCollection(). Retired has no outgoing arrows — it is terminal. Notice that hold expires is fired by a clock, not by an actor.
NORMAL ~/memra/learn/comp-410/state-diagrams-events-guards-actions utf-8 LF