4.5.4 · D5Software Engineering

Question bank — UML — use case, class, sequence, activity, state machine, component diagrams

2,883 words13 min readBack to topic

Part 0 — The glyph primer (see it before you're quizzed on it)

Every trap below hinges on a shape. Two of those shapes look almost identical — the hollow diamond ◇ is reused for aggregation (a class-diagram line-end) and for decision/merge (an activity-diagram node). They mean totally different things. So we draw each family separately.

Class-diagram relationship line-ends

Figure — UML — use case, class, sequence, activity, state machine, component diagrams

Read the figure left to right, weakest "togetherness" to strongest:

  • Association — a plain line ("knows about"). If the line has an open arrowhead on one end (a plain > with no fill), that arrow is navigability: it says "this end can reach the other", not that a message is sent. A line with no arrowhead means either end can reach the other.
  • Aggregation — a hollow (unfilled) diamond ◇ on the whole's end; the part can live on its own.
  • Composition — a filled (solid) diamond ◆ on the whole's end; the part dies with the whole.
  • Inheritance — a hollow (unfilled) triangle ▷ pointing at the parent ("is-a").

Visibility symbols inside a class box

Figure — UML — use case, class, sequence, activity, state machine, component diagrams

Every attribute and operation line starts with a visibility symbol saying who may access it:

  • + = public (anyone).
  • - = private (only this class).
  • # = protected (this class and its subclasses).
  • ~ = package (anything in the same package).

Multiplicity (cardinality) at a line end

Figure — UML — use case, class, sequence, activity, state machine, component diagrams

At each end of an association you may write multiplicity — how many objects can sit at that end:

  • 1 = exactly one (mandatory, and no more).
  • 0..1 = zero or one (optional; at most one).
  • * = zero or more, no upper bound.
  • 1..* = one or more, no upper bound.
  • 1..5 = an explicit range: between one and five.

Use-case stereotype arrows (direction is the whole point)

  • <<include>> — a dashed arrow from the base use case to the included one. The base always pulls it in. (Withdraw → Authenticate.)
  • <<extend>> — a dashed arrow from the extension to the base. The extension optionally reaches in. (Print Receipt → Withdraw.)

Activity-diagram control nodes (diamond vs bar)

  • Decision — a hollow diamond ◇ with one incoming edge and several outgoing guarded [condition] edges; exactly one branch is taken.
  • Merge — the same diamond shape, but used the other way: several incoming edges and one outgoing edge. It brings alternative paths back together and does not wait for anything.
  • Fork — a thick bar ━ with one incoming edge and several outgoing edges that run all at once.
  • Join — a thick bar ━ with several incoming edges and one outgoing edge that waits for every parallel flow before continuing.

Sequence-diagram anatomy and fragments

  • Lifeline — dashed vertical line = the object exists.
  • Activation bar — thin rectangle on the lifeline = the object is running a method right now.
  • Synchronous message (solid line, filled solid arrowhead ▶) = caller waits for a reply.
  • Return (dashed line, open arrowhead) = the reply coming back.
  • Asynchronous message (solid line, open thin arrowhead ⇀, the two half-lines of a >) = caller does not wait; it fires the message and carries on immediately.
  • Fragments boxed with a corner label: alt (if/else), opt (runs zero-or-once), loop (repeats).

State-machine transition label

A transition arrow carries up to three parts: event [guard] / action.

  • event — the trigger that fires the arrow.
  • [guard] — a condition that must be true, or the arrow doesn't fire.
  • /action — what happens as it fires.
Recall Quick glyph check before the quiz

Hollow diamond on a class line ::: aggregation (part survives). Filled diamond on a class line ::: composition (part dies with whole). Open arrowhead on a class association ::: navigability (which end knows the other), not a message. + - # ~ before a class member ::: public, private, protected, package visibility. 1, 0..1, *, 1..* at a line end ::: exactly one, optional, zero-or-more, one-or-more (star = unbounded). Thick bar in an activity flow ::: fork (one-in many-out) or join (many-in one-out, waits). Diamond in an activity flow, one-in many-out ::: decision (choose one, guarded). Diamond in an activity flow, many-in one-out ::: merge (rejoin alternatives, no wait). Filled arrowhead in a sequence diagram ::: synchronous (wait); open arrowhead ::: asynchronous (don't wait) or a return. Dashed arrow base→sub ::: <<include>>; dashed arrow extension→base ::: <<extend>>.


True or false — justify

An <<include>> and an <<extend>> are the same relationship drawn with opposite arrows, so you can swap them freely
False — as figure s02 shows, direction encodes meaning: <<include>> (base→sub) means the base always runs it; <<extend>> (extension→base) means it runs only under a condition. The meaning, not just the arrow, changes.
A class diagram is a behavioural diagram because classes "do things" via their methods
False — a class diagram is structural: it shows what exists and how things are wired, frozen in time. The running of those methods is captured by sequence, activity, or state diagrams.
Composition (◆) and aggregation (◇) are both "has-a", so choosing between them is just style
False — as figure s01 shows, the diamond's fill is the test: filled ◆ = part dies with the whole (House ◆— Room); hollow ◇ = part survives (Library ◇— Book). A real semantic difference, not decoration.
In a sequence diagram, the vertical dashed lifeline shows the exact time the object is executing code
False — in figure s04 the dashed lifeline shows the object exists; the thin activation bar on it shows when it is actively running a method. An object can exist yet be idle.
A fork (━) and a decision (◇) both split one path into many, so either shape works for branching
False — figure s03 makes it visual: a decision ◇ picks exactly one guarded branch; a fork ━ activates all branches at once. Same "one-in-many-out" picture, opposite semantics.
An actor in a use case diagram must be a human being
False — an actor is a role outside the system, and that role can be another system, a clock/timer, or a hardware device. "Human" is a common case, not the definition.
A state machine diagram and an activity diagram are interchangeable because both use arrows between shapes
False — a state machine tracks one object's life (states + events that change them); an activity diagram tracks a process/workflow (steps + control flow). One follows an object, the other follows a task.
Two actors connected to the same use case means the system runs that use case twice
False — it means each actor can, on their own, invoke that goal. Association is about who may use the behaviour, not how many times it executes.
Multiplicity 1..* on a class-diagram line means "somewhere between one and a few"
False — as figure s07 shows, the * means many with no upper bound; 1..* reads "one or more, unbounded above". If you meant a cap you'd write an explicit number like 1..5.
A synchronous message and an asynchronous message differ only in arrowhead shape
Partly false — the arrowhead (solid filled vs open, figure s04) is the notation, but the real difference is behaviour: with synchronous the caller waits for a reply; with asynchronous the caller continues immediately without waiting.
An open arrowhead on a class-diagram association means a message flows in that direction
False — on a class diagram that open arrowhead is navigability (which end can reach the other), a static fact. Message flow is a sequence-diagram idea, not a class-diagram one.

Spot the error

"I drew Withdraw Cash <<include>> Print Receipt because withdrawing usually prints a receipt."
The error is direction and type (see figure s02). Printing is optional, so it should be <<extend>> from Print Receipt to Withdraw Cash<<include>> would force a receipt on every withdrawal.
"My class box shows House ◆—— Room but I let a Room belong to two Houses at once."
The filled diamond in figure s01 means the Room is owned by exactly one whole and dies with it. Sharing a part across two owners contradicts composition — that situation is aggregation (◇), not composition.
"In my sequence diagram I put a loop fragment but I want the loop body to run only when balance is low."
A loop fragment means "repeat"; a condition that may run once or not at all is opt (optional), and a two-way if/else is alt (all three shown in figure s04). loop is the wrong fragment for a single guarded check.
"I used a decision node (◇) to pack items and charge the card at the same time."
A decision picks one path only. To run both simultaneously you need a fork (━), followed later by a join (━), as in figure s03, so nothing proceeds until both finish.
"My turnstile transition is labelled just unlock with no event."
A transition needs an event (the trigger) to fire; unlock is an action (the /action part, see figure s05). The correct label is coin / unlock — event first, action after the slash.
"I merged two parallel flows back together using a merge node (◇)."
A merge (◇, many-in/one-out, figure s03) reunites alternative (either-or) paths and does not wait; parallel flows must be reunited with a join (━), which waits for both. Using a merge would let the flow continue before both branches finish.
"On my class box I marked a private field with +."
+ means public (figure s06). Private is -; you also have # protected and ~ package. The visibility symbol carries real access meaning, so the wrong glyph mis-documents the design.

Why questions

Why does UML split diagrams into structural and behavioural families instead of one universal diagram?
Because a system genuinely has independent viewpoints: "what exists" (structure) and "what happens over time" (behaviour). Debugging structure asks "is the model wrong?"; debugging behaviour asks "is the flow wrong?" — different questions need different pictures.
Why factor Authenticate out with <<include>> instead of copying it into every use case?
Because authentication is shared and never skipped by those use cases. Factoring it out removes duplication so a change to authentication is made in one place, not many.
Why does a sequence diagram put objects across the top and time down the side, rather than showing workflow like an activity diagram?
Because its question is "which object talks to which, in what order". Objects need their own vertical lane so message arrows between them are visible; time flows downward so ordering reads top-to-bottom.
Why does an activity diagram's join make the flow wait rather than just merge?
Because the parallel branches must all be complete before the next step is safe (e.g. don't ship until both packing and charging finish). A join synchronises (many-in/one-out); a plain merge just rejoins alternatives without waiting.
Why label a state-machine transition event [guard] / action with three parts?
The event says what triggers it, the [guard] says the condition that must hold for it to fire, and the /action says what happens as it fires (figure s05). Together they fully specify when and what a transition does.
Why is a use case diagram deliberately free of implementation detail?
Because it is the requirements-level contract — it answers "who are the players and what goals can they reach", agreed with clients before code exists. Adding implementation detail would mix a different viewpoint into it.

Edge cases

What does a self-transition on a Locked state (event push, staying Locked) actually model?
An event that fires but changes nothing — pushing a locked gate is a real event the object receives, yet it stays in the same state. It documents that the event is handled (ignored), not that it's impossible.
An object exists in a scenario but never sends or receives a message — what appears in the sequence diagram?
Its lifeline (dashed line) still appears to show it exists, but it carries no activation bar because it never runs a method. Existence and activity are shown by different marks.
A use case has an actor associated but no <<include>> or <<extend>> links — is the diagram incomplete?
No — plain association (a bare line) is the normal, most common case, meaning the actor can invoke that goal. Include/extend are only needed when behaviour is factored out or conditionally added.
In a state machine, can one object be in two states at once?
In a simple (flat) state machine, no — the object rests in exactly one state at a time; events move it between them. (Concurrent regions are an advanced extension, but the default single-object model is one active state.)
What does multiplicity 0..1 at a line end express, and when is it different from 1?
0..1 means the link is optional — zero or one — whereas 1 means it is mandatory — exactly one must exist (figure s07). The difference matters at object creation: a 1 end must be filled, a 0..1 end may be empty.
If you delete the whole in an aggregation (Library ◇— Book), what happens to the parts?
The parts survive — the books still exist independently and can be moved elsewhere. That surviving-part behaviour is exactly what distinguishes aggregation (◇) from composition (◆), where parts would be destroyed.
Recall One-line rule that resolves most of these traps

Ask the diagram's question first: who/what (use case), what-exists (class), what-order (sequence), how-flows (activity), which-states (state machine). The right shape and semantics follow from the question, not the other way around.