The Activity Diagram
Chapter Twenty-Three
Syllabus topic Module 1, "System Modeling using UML: ... Activity Diagram".
Pages 138 to 143 of 499
In one line
An activity diagram shows how a process flows: actions in rounded boxes, arrows between them in the order they happen, diamonds where the flow chooses a path or comes back together, bars where it splits into parallel paths or waits for them, and swimlanes that show who does each action.
In the wording to use when asked: an activity diagram is a UML behaviour diagram that models the flow of control between actions, with an initial node and final nodes, decision and merge nodes with guarded flows, fork and join nodes for concurrent flows, and activity partitions, drawn as swimlanes, that assign each action to the participant who performs it.
The parts
| Part | What it means | How UML draws it |
|---|---|---|
| Action | one step of the process | a rectangle with rounded corners, named with a verb |
| Control flow | what happens next | an arrow from one node to the next |
| Initial node | where the process starts | a small solid circle |
| Activity final node | the end of the whole process: every flow in it stops | a solid circle inside a hollow one, a bull's eye |
| Flow final node | the end of one flow only; any others carry on | a circle with an X in it |
| Decision node | the flow takes exactly one of several paths | a diamond with one arrow in and several out, each out-arrow labelled with a guard in square brackets |
| Merge node | several paths come back together | a diamond with several arrows in and one out |
| Fork node | the flow splits into paths that run at the same time | a bar with one arrow in and several out |
| Join node | the flow waits until all its incoming paths have arrived | a bar with several arrows in and one out |
| Partition, or swimlane | who performs the actions inside it | a column, or a row, headed with the participant's name |
Decision and merge, fork and join
The two pairs look alike and mean opposite things.
A decision chooses one path, and a merge takes whichever path arrives. Between them, only one of the paths ever runs. Both are diamonds.
A fork starts all of its paths at once, and a join waits for all of them to finish before the flow goes on. Between them, every path runs. Both are bars.
So if an order had to be both packed and billed before it was handed over, and the two could be done at the same time by different people, that would be a fork and a join: the order is handed over only when both are done. When the student either collects the order or does not, that is a decision.
The Activity Diagram
Swimlanes, and who may be in them
A swimlane says who does each action. Unlike a use case diagram, which shows only actors, the people who work the system, an activity diagram may give a lane to anyone in the process, including people who never touch the software. That is often the point of drawing one: it shows where the system fits into how the work is really done.
An activity diagram is not just a flowchart
It looks like one, and for a simple process it is read like one. UML adds three things a flowchart does not have: lanes that assign the work, forks and joins for work done in parallel, and a precise meaning for the two kinds of ending, which the specification defines: an activity final node stops every flow in the activity, a flow final node only its own.
Drawing one
- Choose one process, from a use case or from the organisation's own work: "an order from the student's side", "serving an order".
- List who takes part, and give each a lane.
- Write the actions in order, each a verb phrase, in the lane of whoever does it.
- Put every choice in a decision diamond in the lane of whoever makes it, and label every outgoing arrow with its guard.
- Bring alternative paths back together with a merge, and parallel paths with a join.
- End with an activity final node.
- Check each action against the requirements and, where the system does it, against the code.
The worked diagrams
Ordering, from the student's side
Figure 23.1 Placing an order, from the student's side
@startuml activity-place-order
!pragma layout smetana
|Student|
start
repeat
:Choose food
and a slot;
:Tap Place order;
|System|
:Check the slot and
earlier orders, and
take the stock, all
or nothing;
backward:Say why;
repeat while (Refused?) is (yes)
->no;
:Save the order
with its number;
|Student|
:Note the number;
stop
@endumlThe diagram is a loop. The student chooses food and a slot and taps Place order. The system makes one attempt, all or nothing: it checks the slot and the student's earlier orders, and takes the stock of every item, and either all of that succeeds or none of it happens. At the decision "Refused?", the system either says why, and the flow goes back, through the merge at the top, to the student choosing again; or it saves the order with its number, which the student notes.
The decision is in the System lane, because the system decides. The loop is drawn with a merge at the top and the decision at the bottom, which is how an activity diagram draws "repeat until".
Serving, from the counter's side
Figure 23.2 Serving an order, from the counter's side
The Activity Diagram
@startuml activity-serve-order
!pragma layout smetana
|Counter|
start
:Start
preparing;
|Kitchen|
:Cook the
dishes;
|Counter|
:Mark ready;
if (Student
in time?) then (no)
:Mark not
collected;
else (yes)
|Student|
:Give the
number
and pay;
|Counter|
:Mark
collected;
endif
stop
@endumlThree lanes. The counter taps Start preparing; the kitchen cooks the dishes; the counter taps Mark ready. Then the one real decision of serving: does the student come before the break ends? If not, the counter marks the order not collected. If so, the student gives the number and pays, and the counter marks it collected. The two paths meet at a merge, and the activity ends.
The kitchen has a lane, but is not an actor. No cook ever signs in, so the kitchen is not in the use case diagram (Chapter 20). But the kitchen does real work in this process, and the diagram would be false without it.
What the first drawings got wrong
Both activity diagrams were redrawn when the team checked them against the code of the first increment, in version 1.1 of the UML set (Chapter 35).
Check, then take. The first ordering diagram had two actions, "Check the slot and the stock" and then, after the decision, "Take the stock". That describes exactly the mistake the system is designed to avoid: between checking and taking, another student can take the last plate, and two students are both promised it. The code checks and takes in one statement (Chapter 22). The diagram now shows one all-or-nothing action, so it says what the code does.
The decision in the wrong lane. "Accepted?" sat in the Student lane, as if the student decided whether their own order was accepted. It is the system's decision, so it moved to the System lane.
No kitchen. The first serving diagram had only the counter and the student, so the dishes appeared to cook themselves.
When a state machine says it better
An activity diagram follows a process from step to step. Sometimes the question is different: what can happen to one thing over its life? An order is placed, prepared, made ready, collected, or cancelled, or never collected. The rule FR-15 states is not a process; it is a list of which status may follow which, and who may make each move.
That is what a state machine diagram, another UML behaviour diagram, is for:
- A state is a condition the thing can be in: a rectangle with rounded corners.
- The initial pseudostate, a small solid circle, points to the first state.
- A final state, a circle around a small solid circle, is where its life ends.
- A transition is an arrow from one state to another, labelled in UML's form
trigger [guard] / effect: what makes it happen, the condition that must hold, and what the system does as it happens. Any part may be left out.
The Activity Diagram
The worked state machine
Figure 23.3 An order's life: its six states and the five moves between them
@startuml order-states
!pragma layout smetana
hide empty description
[*] --> placed : order accepted
placed --> preparing : counter taps\nStart preparing
placed --> cancelled : student cancels\n/ stock returned
preparing --> ready : counter taps\nMark ready
ready --> collected : counter taps\nCollected and paid
ready --> no_show : counter taps\nNot collected
cancelled --> [*]
collected --> [*]
no_show --> [*]
@endumlSix states and five transitions between them. Each trigger names the button that fires it on the counter's screen, word for word: Start preparing, Mark ready, Collected and paid, Not collected. Only one transition has an effect: when a student cancels, the stock is returned, so the portions go back on sale. When an order is not collected there is no effect, and that is deliberate: the food was cooked, and it is gone.
The diagram is the code's rule, drawn. The application stores exactly these moves, and who may make each:
// Which status may follow which, and whose move it is.
const MOVES = {
placed: { preparing: 'counter', cancelled: 'student' },
preparing: { ready: 'counter' },
ready: { collected: 'counter', no_show: 'counter' },
};and decides in one place that only a cancelled order returns its stock:
// A cancelled order gives its food back to the stock. A
// no-show does not: that food was cooked and is gone.
function returnsStock(to) {
return to === 'cancelled';
}Every arrow of the state machine is an entry in MOVES, and every entry in MOVES is an arrow. Any other move, such as placed straight to ready, is refused (Chapter 43).
Do this for your project
- Draw an activity diagram for each process your system changes: how the work is done with it, including the people who never use it.
- Give every participant a lane, and put each decision in the lane of whoever decides.
- Never split an operation that must be all or nothing into "check" and "do" in your diagram, or in your code.
- Use a fork and a join only for work that really happens at the same time, and a decision and a merge for choices.
- If your system has something that moves through statuses, such as an order, a booking or an application, draw its state machine, and make your code's rule table match it exactly.
Mistakes that cost marks
A decision drawn as a fork, or a fork as a decision: bars mean "all paths", diamonds "one path".
The Activity Diagram
Guards missing from a decision's arrows, so nobody can tell which way the flow goes.
Decisions in the wrong lane. Whoever makes the choice owns the diamond.
Paths that never end, or end in mid-air, with no final node.
A flowchart of the code, with "i = i + 1" as an action. An activity diagram of a process is about the work, in the words of the people who do it.
Statuses drawn as an activity diagram. If the question is "what can happen to this order", draw a state machine.
Quick revision
- Action: rounded rectangle. Initial node: solid circle. Activity final: bull's eye, stops every flow. Flow final: circle with an X, stops one flow.
- Decision and merge: diamonds, one path runs. Fork and join: bars, all paths run; a join waits for all of them.
- Guards in square brackets on a decision's outgoing arrows.
- Swimlanes show who does each action, and may include people who never use the system.
- A state machine follows one thing through its life: states (rounded rectangles), transitions labelled
trigger [guard] / effect, an initial pseudostate and a final state.
Questions you must be able to answer
1. What does an activity diagram show, and what are swimlanes for? The flow of a process from action to action, with its choices, its parallel paths and its ends. Swimlanes divide the actions by who performs them, so the diagram shows who does what as well as in what order.
2. Distinguish a decision node from a fork node. A decision, a diamond, sends the flow down exactly one of its outgoing paths, the one whose guard is true. A fork, a bar, sends it down all of its outgoing paths at once, to run in parallel; a join then waits for all of them.
3. What is the difference between an activity final node and a flow final node? An activity final node, a bull's eye, ends the whole activity: every flow in it stops. A flow final node, a circle with an X, ends only the flow that reaches it, and any other flows carry on.
4. Why is the kitchen a lane in the serving diagram but not an actor in the use case diagram? Because an actor must interact with the system, and no cook signs in; but the kitchen does real work in the serving process, and an activity diagram describes the process, including people who never use the system.
5. What was wrong with drawing "check the stock" and "take the stock" as two actions? It describes a check-then-act race: between the check and the taking, another student can take the last portion, and both are promised it. The system checks and takes in one indivisible step, and the diagram must show one all-or-nothing action.
The Activity Diagram
6. When would you draw a state machine diagram instead of an activity diagram? When the question is what can happen to one thing over its life rather than how a process flows: its states, the events that move it between them, the conditions and the effects. The worked order's statuses and the moves allowed between them are a state machine, and the code's rule table matches its arrows exactly.
The rest of this subject
These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.