Use-case and activity diagrams
Part of the free Low-Level Design course on LogicWiz, in the chapter: Modelling behaviour: sequence, state, use-case and activity diagrams. The class-diagram exercises run in the app.
Use-case and activity diagrams
"Before the classes, show me on one page who uses this app and what they can do."
Priya, in a mock round
Two more diagrams interviewers ask for
Arjun already draws three diagrams. A class diagram shows which classes exist and how they relate. A sequence diagram shows the order of calls in one scenario. A state diagram shows the life of one object.
In his mock round Priya asked for two more. The first was a picture of the people and systems that use SwiftKart, and what each can do. The second was a picture of the whole checkout as steps, with every branch. Neither shows classes or calls. They sit one step earlier: they show what the system is for, and how the work flows.
- A use-case diagram answers "who uses the system, and for what?"
- An activity diagram answers "what steps happen, in what order, with which branches?"
The use-case diagram
A use case is one thing a user wants to get done, such as "Place order". An actor is a person or an outside system that takes part: the customer, a rider, the payment gateway. The system boundary is a box around the use cases. Whatever is inside, you build. Actors stand outside.
flowchart LR
cust["Customer"] --- place
cust --- track
rider["Rider"] --- deliver
pg["Payment gateway"] --- payo
subgraph SK["SwiftKart app"]
place(["Place order"])
track(["Track order"])
deliver(["Deliver order"])
payo(["Pay for order"])
coupon(["Apply coupon"])
end
place -.->|include| payo
coupon -.->|extend| place
Actors come in two kinds. A primary actor starts a use case: the customer taps Place order. A secondary actor is called by the system while the use case runs: the payment gateway answers when asked to charge. Both stand outside the box. The lines between actor and use case only say "takes part in". They do not say who calls whom.
The notation here is simplified. Standard UML draws an actor as a stick figure and a use case as an oval, and joins them with a plain line. Mermaid cannot draw stick figures, so actors are plain boxes and use cases are rounded shapes. Plain lines have no arrowheads, which matches UML. On a whiteboard, draw the real shapes.
Two relationships between use cases cause most confusion:
- Include means "always part of". Placing an order always includes paying for it, so the dashed arrow goes from "Place order" to "Pay for order". Think of a meal deal: the drink is always in the box.
- Extend means "an optional extra". A coupon is not needed to place an order, so the dashed arrow goes from "Apply coupon" to "Place order", from the extra to the thing it extends. Think of extra cheese on a pizza: the pizza stands without it.
Both comparisons stop at one point. The diagram does not say when the payment or the coupon happens. For the order of steps you need an activity or sequence diagram.
To remember the directions: an include arrow points at the part that is always needed, and an extend arrow points at the thing being extended. Name a use case with a verb and a noun, from the actor's point of view. "Place order" is a use case. "Save to database" is not, because no actor wants that.
From the requirements you clarify to use cases
Arjun said: "Use-case diagrams are for analysts, not for programmers. I will start with classes." Priya showed him why not. In the first five minutes of a round you ask clarifying questions. Each answer changes the use-case diagram, so the diagram records your scope on one page.
| Question and answer | Change to the diagram |
|---|---|
| "Can customers cancel?" "Yes, before packing." | Add the use case "Cancel order" |
| "Do riders use the app?" "Yes." | Add the actor "Rider" and "Deliver order" |
| "Are coupons required?" "No, optional." | Add "Apply coupon" with an extend arrow |
| "Is refund in scope?" "Not now." | Leave it out, and say so aloud |
Leaving a use case out is a decision, not an accident. Say "refunds are out of scope" and the interviewer can agree or correct you early. The list of use cases also becomes the scope comment at the top of your main, the way the machine-coding lesson suggests.
The diagram leads straight to code. Each use case becomes a method on a service class: "Place order" becomes OrderService.placeOrder. Each noun in the use case points to a class: a customer, a cart, an order, order lines, a coupon. Each outside actor that your code must call, like the payment gateway, becomes an interface. You will do this derivation in the exercise.
The activity diagram
A use case says what a customer can do. An activity diagram shows how the work goes, step by step. These are the shapes, with the UML name first:
- Initial node: a filled circle where the flow starts.
- Action: a rounded box with one step in it, such as "Reserve stock".
- Decision: a diamond with one arrow in and several out. Each outgoing arrow carries a guard, a condition such as "approved" or "declined", just as in a state diagram.
- Fork and join: a thick bar that splits one flow into steps that run at the same time, and a second bar that waits for all of them.
- Final node: a circle with a ring around it, where the flow ends.
Here is SwiftKart's checkout. Mermaid has no thick bars or rounded action boxes, so fork and join are small labelled boxes and actions are plain boxes.
flowchart TD
S(("Start")) --> A["Review cart"]
A --> D1{"Coupon entered?"}
D1 -->|"yes"| C["Apply coupon if valid"]
D1 -->|"no"| R["Reserve stock"]
C --> R
R --> D2{"All items in stock?"}
D2 -->|"no"| X["Show out of stock"]
D2 -->|"yes"| P["Charge payment"]
P --> D3{"Approved?"}
D3 -->|"declined"| REL["Release stock"]
D3 -->|"approved"| SV["Save order"]
SV --> F["Fork"]
F --> N1["Tell store to pack"]
F --> N2["Send confirmation"]
N1 --> J["Join"]
N2 --> J
X --> E((("End")))
REL --> E
J --> E
Read it from the top. The coupon branch rejoins the main flow at "Reserve stock", so that box has two arrows coming in. After the order is saved, "Tell store to pack" and "Send confirmation" can run at the same time. The join waits until both finish. Three flows reach the end: out of stock, a declined payment and success.
Two shapes look alike and mean different things. A diamond is a decision: the flow takes exactly one of its outgoing arrows. A bar is a fork: the flow takes all of them at once. When a flow comes back together, a diamond merges alternatives, and a bar joins parallel work, so each close matches the way it opened. Arjun first drew the fork as a diamond, which said "either tell the store or send the message". Each job needs to happen every time, so only a fork is right.
Checking the diagram finds gaps. If a payment is declined, the diagram shows stock being released. Without the drawing, Arjun's first code forgot it.
Activity or sequence: which one to draw
Both diagrams can show checkout. They answer different questions.
| Question | Draw |
|---|---|
| "Who calls whom, and in what order?" | Sequence diagram |
| "What are the steps, and what are all the branches?" | Activity diagram |
| "What happens at the same time?" | Activity diagram |
| "What does this one object go through?" | State diagram |
A sequence diagram needs objects across the top, so you must know the classes. An activity diagram needs only steps, so you can draw it early, before the classes exist, and a non-programmer can read it. When the interviewer says "walk me through checkout including failures", an activity diagram is the faster answer.
Swimlanes divide an activity diagram into columns, one for each actor or class, so each step sits under the one that does it. "Tell store to pack" would sit under the store, and "Charge payment" under the payment gateway. Lanes show who is responsible. More than four lanes become hard to read, and the lines between them tangle. For a round, a plain activity diagram is enough.
💡 Tip: Do not draw everything. One use-case diagram with five to eight use cases, and one activity diagram for the flow with the most branches, is a good set for a round.
Practice: from "Place order" to classes
Read the use case "Place order" again: a customer fills a cart, may add a coupon, pays through the gateway, and gets an order with lines. Add the classes its nouns suggest, and the one method its verb suggests.
📌 Summary: A use-case diagram shows actors, use cases and the system boundary: your scope on one page. An activity diagram shows steps, decisions and parallel work. Draw it when branches and failures matter.
What Arjun learns next
Arjun can now draw every diagram a round asks for. Next he learns to write code that survives a review: what to do when something goes wrong, how to choose a list, set or map, how to test, and where each class lives.
Check your understanding
- Placing an order always needs paying for it. How do you draw that in a use-case diagram?
- Where does the payment gateway go in SwiftKart's use-case diagram?
- The interviewer asks: "Walk me through checkout, including out of stock, a declined payment, and what can happen at the same time after the order is saved." Which diagram fits best?
- A candidate lists the use case "Save order to database". What is the problem?