Behaviour: sequence and activity
Lesson 4 of 6
4Behaviour: sequence and activity
Two diagrams that photograph time rather than structure. The first answers “who calls whom, in what order?” and the second “what are a process's steps and decisions?”, and we will see one of them expose a bug a class diagram can never show.
What the picture shows: The messages appear in the order they happen: the member asks, the library checks overdue and then the limit, then creates the loan. That order decides the reason a refusal gives.
Map of this part
The concepts in order, click any one to jump to it:
Two ways into the same idea
A class diagram is a photo of the empty house. A sequence diagram is a video of a day in it: who called whom, and in what order. An activity diagram is a step map, like a recipe with "if the dough is sticky, add flour". Some faults show only in the video.
A sequence diagram has lifelines, synchronous and asynchronous messages and alt and loop frames, and exposes ordering bugs and races. An activity diagram has steps, decision nodes and parallel forks, and describes a workflow. Both show behaviour over time, not structure.
Required fundamentals
Part three
The class diagram executed, and the bug running it exposed in the order of the checks.
Conditions and branches
if and else. Both diagrams here are just drawings of that.
The idea of layers
That a system is not one block: an interface calls logic that calls a store. A sequence diagram is entirely about those calls.
Core concepts
Sequence: who calls whom, in what order? Its axis is the participants and the messages between them. Activity: what are a process's steps and decisions? Its axis is the steps and the conditions. The first exposes layers; the second exposes branches.
Each participant in a sequence diagram is a vertical column, and time runs downward. A message is a horizontal arrow; a reply is a dashed one. That is all you need to read any sequence diagram.
alt for a conditional branch, loop for a loop, opt for an optional step. Without these frames the diagram is only the happy path, the most drawn and least useful thing there is.
In an activity diagram a diamond is a decision: one arrow in, several out, labelled with the conditions. Every diamond in the drawing is an if in the code, and the order of the diamonds is the order of the checks.
An activity diagram forces you to order the conditions, exactly what a class diagram cannot do, which is why it is about to fix the previous part's bug.
They describe neither structure nor data, and become unreadable beyond about ten participants or twenty steps. Whoever draws a sequence diagram for every function is not documenting, they are rewriting the code as pictures.
How it works
Diagram 1, Borrowing as a sequence: note the alt frame makes refusal a first-class path, not an afterthought
Diagram 2, Borrowing as an activity: three diamonds, that is three conditions in a deliberate order
| Sequence | Activity | |
|---|---|---|
| The question | Who calls whom? | What steps and decisions? |
| The axis | Participants and messages | Steps and conditions |
| Exposes | Layers and dependencies | Branches and order |
| Good for | Designing interfaces between components | Business rules and checks |
| In the code | Who calls whom | The order of the ifs |
The exercise: the activity diagram fixes the previous part's bug
In part three we ran the diagram and the system told a member who was both overdue and at the limit only that they had “reached the limit”. The message is true and misleading: they will return a copy, try again, and be refused for a reason they were never told. The class diagram could not expose this because it has no concept of order. The activity diagram above does.
The order the class diagram happened to produce:
# the order the class diagram happened to produce
if len(member.active()) >= MAX_LOANS:
raise ValueError("%s already holds %d copies" % (member.name, MAX_LOANS))
if member.overdue(today):
raise ValueError("%s is overdue and may not borrow" % member.name)And the order the activity diagram demands:
# the order the activity diagram demands: the blocking reason first
if member.overdue(today):
raise ValueError("%s is overdue and may not borrow" % member.name)
if len(member.active()) >= MAX_LOANS:
raise ValueError("%s already holds %d copies" % (member.name, MAX_LOANS))$ python3 order_fix.py # member is overdue AND at the limit before the fix -> Muath already holds 5 copies after the fix -> Muath is overdue and may not borrow $ python3 order_fix.py --one # member is overdue with one loan before the fix -> Amal is overdue and may not borrow after the fix -> Amal is overdue and may not borrow
And what did the sequence diagram expose?
Look at the S->>S: check eligibility arrow in the drawing. The system checks eligibility itself, not the store. Had the arrow been S->>D: check eligibility, the “5 copies” rule would have taken up residence in the database, so the business rule would be spread across two layers and nobody would know where to change it.
alt frame and an activity diagram with no diamond both describe the best day of the system's life, and the best day is not what we design for. The test: if your diagram contains not one refusal path, you drew a wish rather than behaviour.| Symbol | What it means | In code |
|---|---|---|
| Vertical column | A participant | An object or a service |
| Solid arrow | A message / call | A function call |
| Dashed arrow | A reply | The return value |
| Arrow back to the same column | A self-call | Internal logic, the rule lives here |
alt | A conditional branch | if / else |
loop | Repetition | for / while |
| Diamond | A decision | if, and its order matters |
| Rounded rectangle | A start or an end | The function's entry and exit |
Myth vs. reality
| The myth | The reality |
|---|---|
| “Sequence and activity are much the same diagram.” | The first's axis is who; the second's is what, in what order. Two entirely different questions. |
| “The order of conditions is an implementation detail.” | We watched it give a user a misleading reason and get them refused twice. Order is part of behaviour. |
| “A diagram without branches is cleaner.” | It is cleaner because it is incomplete. Refusal is half the behaviour, and the alt frame is where it belongs. |
| “Draw a sequence diagram for every function.” | That is rewriting the code as pictures. Draw one when the question is “where should this logic live?”. |
| “A self-call is a redundant line.” | It is the most important line in the diagram: it says the rule lives here, not in the store and not in the interface. |
Try it yourself
A member is overdue and holds 5 copies. Which message serves them better, and why?
Because returning any copy fixes “the limit” and does not fix “overdue”: tell them about the limit and they will try again and be refused for a new reason. The rule: check the narrowest-to-fix reason first. The fourth option looks generous but buries the actionable part in prose.
A sequence diagram contains the arrow S->>D: check eligibility. What does that say about your architecture?
The arrow fixes where the rule lives. If it lives in the store (a trigger, a constraint, a stored procedure) it will be changed somewhere the application programmer never looks, and it will differ between environments. Which is why the self-call S->>S is not a redundant line but an architectural decision.
Quick review flashcards
alt do?if in code, and the order of diamonds is the order of the checks.Check your understanding
1. In one sentence: why could the class diagram not expose the check-order bug?
Because a class diagram is a still photograph: it says the rules exist and has no concept of “before” and “after”. The order of checks is behaviour, so it belongs in an activity diagram.
2. Explain in detail the “narrowest-to-fix first” rule.
Every refusal reason has a “remedy” the user owns. The remedy for “at the limit” is returning any copy; for “overdue” it is returning the overdue copy specifically; and “the copy is unavailable” has no remedy the user owns at all. So checking from narrowest remedy to widest guarantees that the first message they see is the one that works if they act on it, instead of looping through refusals with advice that is not enough. In our drawing “unavailable” came first because it is not their fault, then “overdue”, then “the limit”.
3. (Spot the bug) A sequence diagram starts with an arrow from “UI” straight to “Database”. What is wrong?
It skips the logic layer. And the problem is not cosmetic: if the interface writes straight to the database, none of the three conditions is checked, because the conditions live in the logic, as the self-call said. Every arrow that skips a layer skips that layer's rules with it.
4. The client wants to add “reserve a copy” when none is available. What changes in both diagrams?
In the activity diagram: the first diamond's “No” branch becomes a “create a reservation” node rather than merely “offer a reservation”, and it may need a new diamond (“already has a reservation on this book?”). In the sequence diagram: a new message from the system to the store to create the reservation, and probably a message to an external actor (a notification) when the copy comes back. And the question the drawing will expose: who gets priority if two people reserve?, a question that would never have surfaced without drawing.
5. (Decision) The team proposes a sequence diagram for every API endpoint (35 of them). Your answer?
That this is not design but a second copy of the code in pictures, and it will rot with the first change. The alternative: draw sequences for the operations where a request crosses three or more layers, or where the system deals with an external actor (payment, notification, another system), usually three or four operations, not 35. For the rest, a single activity diagram of the shared validation rules serves them all. A diagram that answers no question is not read, and a diagram that is not read becomes silently wrong.
Resources for this part
Sorted by kind: start with the official docs when you want the precise reference, or with an article or video when you want the explanation first.
Resources for this lesson
Grouped by type. Start with the official docs for precision, or an article or video for the explanation.
Articles2
Done with this lesson?
Sign in to save your progress.