Unlocking System Behavior with UML Sequence Diagrams
Introduction: The “Who, What, and When” of Systems
Imagine walking into a coffee shop. You place an order with the barista, the barista sends the ticket to the kitchen, the kitchen makes the coffee, and finally, the barista hands it to you. This entire process is a sequence of interactions happening over time.
In software engineering, we need a way to visualize these step-by-step interactions between different parts of a system. This is exactly what Unified Modeling Language (UML) Sequence Diagrams do. They show us who is talking to whom, what they are saying, and in what order.
Learning Objectives
By the end of this chapter, you will be able to:
Identify the core components of a sequence diagram: Lifelines and Messages.
Differentiate between synchronous, asynchronous, and return messages.
Model conditional logic using ALT and OPT fragments.
Model repetitive behavior using LOOP fragments.
Part 1: The Basics – Lifelines and Messages
To manage your cognitive load, we will start with just the two most fundamental building blocks: the entities communicating, and the communications themselves.
1. Lifelines (The “Who”)
A lifeline represents an individual participant in the interaction. It is drawn as a box at the top (with the participant’s name) and a dashed vertical line extending downwards. Time flows from top to bottom along this dashed line.
2. Messages (The “What”)
Messages are the communications between lifelines. They are drawn as horizontal arrows. UML 2 distinguishes three main arrow styles (sources: Fowler, UML Distilled, ch. 4; Rumbaugh, Jacobson & Booch, The Unified Modeling Language Reference Manual):
Synchronous Message — solid line with filled (triangular) arrowhead. The sender blocks until the receiver responds, like calling a method and waiting for it to return.
Asynchronous Message — solid line with open (stick) arrowhead. The sender fires the message and continues immediately, like posting an event to a queue or invoking a callback you don’t wait for.
Return Message — dashed line with open arrowhead. Represents control (and often a value) returning to the original caller. Return arrows are optional in UML 2: include them when the returned value is important, omit them when a synchronous call obviously returns.
⚠ Common mistake: Students often confuse the filled vs. open arrowhead, treating both as synchronous. The rule: filled = blocks, open = fires-and-forgets. Remember it as “filled is full commitment; open lets go.”
Visualizing the Basics: A Simple ATM Login
Let’s look at the sequence of a user inserting a card into an ATM.
Detailed description
UML sequence diagram with 3 participants (Customer, ATM, Bank Server). Messages: customer calls atm with "insertCard()"; atm calls bank with "verifyCard()"; bank replies to atm with "cardValid()"; atm calls customer with "promptPIN()".
Participants
Customer
ATM
Bank Server
Messages
1. customer calls atm with "insertCard()"
2. atm calls bank with "verifyCard()"
3. bank replies to atm with "cardValid()"
4. atm calls customer with "promptPIN()"
Notice the flow of time: Message 1 happens first, then 2, 3, and 4. The vertical dimension is strictly used to represent the passage of time.
Stop and Think (Retrieval Practice): If the ATM sent an alert to your phone about a login attempt but didn’t wait for you to reply before proceeding, what type of message arrow would represent that alert? (Think about your answer before reading on).
Reveal Answer
An asynchronous message, represented by an open/stick arrowhead, because the ATM does not wait for a response.
Part 1.5: Activation Bars and Object Naming
Now that you understand the basic elements, let’s add two important details that appear in real-world sequence diagrams.
Activation Bars (Execution Specifications)
An activation bar (also called an execution specification) is a thin rectangle drawn on a lifeline. It represents the period during which a participant is actively performing an action or behavior—for example, executing a method. Activation bars can be nested across software lifelines and within a single lifeline (e.g., when an object calls one of its own methods). Human actors are usually shown as initiators or recipients, not as executing software behavior, so they normally do not need activation bars.
Detailed description
UML sequence diagram with 3 participants (Passenger, Station, Train). Messages: passenger calls station with "requestStop()"; station calls train with "addStop()"; train replies to station with "stopScheduled"; station replies to passenger with "confirmation"; train calls train with "openDoors()"; passenger calls station with "requestClose()"; station calls train with "closeDoors()"; train replies to station with "doorsClosed"; station replies to passenger with "confirmation".
Participants
Passenger
Station
Train
Messages
1. passenger calls station with "requestStop()"
2. station calls train with "addStop()"
3. train replies to station with "stopScheduled"
4. station replies to passenger with "confirmation"
5. train calls train with "openDoors()"
6. passenger calls station with "requestClose()"
7. station calls train with "closeDoors()"
8. train replies to station with "doorsClosed"
9. station replies to passenger with "confirmation"
The blue bars show when each object is actively processing. Notice how the Station is active from when it receives requestStop() until it sends the confirmation, and how the Train has separate execution bars for addStop(), openDoors(), and closeDoors().
Object Naming Convention
Lifelines in sequence diagrams represent specific object instances, not classes. The standard naming convention is:
objectName : ClassName
If the specific object name matters:
If only the class matters: (anonymous instance)
Multiple instances of the same class get distinct names:
This is different from class diagrams, which show classes in general. Sequence diagrams show one particular scenario of interactions between concrete instances.
Consistency with Class Diagrams
When you draw both a class diagram and a sequence diagram for the same system, they must be consistent:
Every message arrow in the sequence diagram must correspond to a method defined in the receiving object’s class (or a superclass).
The method names, parameter types, and return types must match between the two diagrams.
Part 2: Adding Logic – Combined Fragments
Real-world systems rarely follow a single, straight path. Things go wrong, conditions change, and actions repeat. UML uses Combined Fragments to enclose portions of the sequence diagram and apply logic to them.
Fragments are drawn as large boxes surrounding the relevant messages, with a tag in the top-left corner declaring the type of logic, such as , , , or .
Common fragment syntax in sequence diagrams:
Optional behavior:
Alternatives with guarded branches:
Repetition:
Parallel branches:
Early exit:
Critical region:
Interaction reference:
1. The OPT Fragment (Optional Behavior)
The opt fragment is equivalent to an if statement without an else. The messages inside the box only occur if a specific condition (called a guard) is true.
Scenario: A customer is buying an item. If they have a loyalty account, they receive a discount.
Detailed description
UML sequence diagram with 2 participants (Checkout System, Pricing Engine). Messages: checkout calls pricing with "calculateTotal()"; pricing replies to checkout with "subtotal"; in optional fragment [hasLoyaltyAccount == true], checkout calls pricing with "applyDiscount()"; pricing replies to checkout with "discountApplied()".
Participants
Checkout System
Pricing Engine
Combined fragments
optional fragment [hasLoyaltyAccount == true]
Messages
1. checkout calls pricing with "calculateTotal()"
2. pricing replies to checkout with "subtotal"
3. in optional fragment [hasLoyaltyAccount == true], checkout calls pricing with "applyDiscount()"
4. pricing replies to checkout with "discountApplied()"
Notice the [hasLoyaltyAccount == true] text. This is the guard condition. If it evaluates to false, the sequence skips the entire box.
2. The ALT Fragment (Alternative Behaviors)
The alt fragment is equivalent to an if-else or switch statement. The box is divided by a dashed horizontal line. The sequence will execute only one of the divided sections based on which guard condition is true.
Scenario: Verifying a user’s password.
Detailed description
UML sequence diagram with 2 participants (System, Database). Messages: in alt branch [password is correct], system calls db with "checkPassword()"; db replies to system with "loginSuccess()"; in alt branch [password is incorrect], system calls db with "checkPassword()"; db replies to system with "loginFailed()".
Participants
System
Database
Combined fragments
alt branch [password is correct]
alt branch [password is incorrect]
Messages
1. in alt branch [password is correct], system calls db with "checkPassword()"
2. db replies to system with "loginSuccess()"
3. in alt branch [password is incorrect], system calls db with "checkPassword()"
4. db replies to system with "loginFailed()"
3. The LOOP Fragment (Repetitive Behavior)
The loop fragment represents a for or while loop. The messages inside the box are repeated as long as the guard condition remains true, or for a specified number of times.
Scenario: Pinging a server until it wakes up (maximum 3 times).
Detailed description
UML sequence diagram with 2 participants (App, Server). Messages: in loop [up to 3 times], app calls server with "ping()"; server replies to app with "ack()".
Participants
App
Server
Combined fragments
loop [up to 3 times]
Messages
1. in loop [up to 3 times], app calls server with "ping()"
2. server replies to app with "ack()"
Part 3: Putting It All Together (Interleaved Practice)
To truly understand how these elements work, we must view them interacting in a complex system. Combining different concepts requires you to interleave your knowledge, which strengthens your mental model.
The Scenario: A Smart Home Alarm System
The user arms the system.
The system checks all windows.
It loops through every window.
If a window is open (ALT), it warns the user. Else, it locks it.
Optionally (OPT), if the user has SMS alerts on, it texts them.
Detailed description
UML sequence diagram with 4 participants (User, Alarm Hub, Window Sensors, SMS API). Messages: user calls hub with "armSystem()"; in loop [for each window], hub calls sensors with "getStatus()"; sensors replies to hub with "statusData()"; in loop [for each window], within alt branch [status == "Open"], hub replies to user with "warn()"; in loop [for each window], within alt branch [status == "Closed"], hub calls sensors with "lock()"; in optional fragment [smsEnabled == true], hub calls sms with "sendText("Armed")".
Participants
User
Alarm Hub
Window Sensors
SMS API
Combined fragments
loop [for each window]
alt branch [status == "Open"]
alt branch [status == "Closed"]
optional fragment [smsEnabled == true]
Messages
1. user calls hub with "armSystem()"
2. in loop [for each window], hub calls sensors with "getStatus()"
3. sensors replies to hub with "statusData()"
4. in loop [for each window], within alt branch [status == "Open"], hub replies to user with "warn()"
5. in loop [for each window], within alt branch [status == "Closed"], hub calls sensors with "lock()"
6. in optional fragment [smsEnabled == true], hub calls sms with "sendText("Armed")"
Part 4: Combined Fragment Reference
The three fragments above (opt, alt, loop) are the most common, but UML defines additional fragment operators:
Fragment
Meaning
Code Equivalent
ALT
Alternative branches (mutual exclusion)
if-else / switch
OPT
Optional execution if guard is true
if (no else)
LOOP
Repeat while guard is true
while / for loop
PAR
Parallel execution of fragments
Concurrent threads
CRITICAL
Critical region (only one thread at a time)
synchronized block
BREAK
Early exit from the rest of the enclosing fragment (its operand is performed instead of the remaining messages)
break / early return
REF
Reference to another sequence diagram by name
Function / subroutine call
When to use ref: When a shared interaction (e.g., login, authentication, checkout) appears in many sequence diagrams, draw it once as its own diagram and reference it from others with a ref frame. This is the sequence-diagram equivalent of factoring out a function.
Part 5: From Code to Diagram
Translating between code and sequence diagrams is a critical skill. Let’s work through a progression of examples.
UML sequence diagram with 3 participants (Register, Sale, Payment). Messages: register calls sale with "makePayment(cashTendered)"; sale replies to payment with "<<create>>"; sale calls payment with "authorize()".
Participants
Register
Sale
Payment
Messages
1. register calls sale with "makePayment(cashTendered)"
2. sale replies to payment with "<<create>>"
3. sale calls payment with "authorize()"
Notice how the Payment constructor call becomes a create message in the sequence diagram. The Payment object appears at the point in the timeline when it is created.
UML sequence diagram with 2 participants (A, B). Messages: a calls b with "makeNewSale()"; in loop [more items], a calls b with "enterItem(itemID, quantity)"; b replies to a with "description, total"; a calls b with "endSale()".
Participants
A
B
Combined fragments
loop [more items]
Messages
1. a calls b with "makeNewSale()"
2. in loop [more items], a calls b with "enterItem(itemID, quantity)"
3. b replies to a with "description, total"
4. a calls b with "endSale()"
The for loop in code maps directly to a loop fragment. The guard condition [more items] is a Boolean expression that describes when the loop continues.
Example 3: Alt Fragment to Code
Given this sequence diagram:
Detailed description
UML sequence diagram with 3 participants (A, B, C). Messages: o calls a with "doX(x)"; in alt branch [x < 10], a calls b with "calculate()"; in alt branch [else], a calls c with "calculate()".
Participants
A
B
C
Combined fragments
alt branch [x < 10]
alt branch [else]
Messages
1. o calls a with "doX(x)"
2. in alt branch [x < 10], a calls b with "calculate()"
3. in alt branch [else], a calls c with "calculate()"
Quick Check (Generation): Try translating this code into a sequence diagram before checking the answer:
publicclassOrderProcessor{publicvoidprocess(Orderorder,Inventoryinv){if(inv.checkStock(order.getItemId())){inv.reserve(order.getItemId());order.confirm();}else{order.reject("Out of stock");}}}
Reveal Answer
Detailed description
UML sequence diagram with 3 participants (OrderProcessor, Inventory, Order). Messages: proc calls inv with "checkStock(itemId)"; inv replies to proc with "inStock"; in alt branch [inStock == true], proc calls inv with "reserve(itemId)"; proc calls order with "confirm()"; in alt branch [inStock == false], proc calls order with "reject("Out of stock")".
Participants
OrderProcessor
Inventory
Order
Combined fragments
alt branch [inStock == true]
alt branch [inStock == false]
Messages
1. proc calls inv with "checkStock(itemId)"
2. inv replies to proc with "inStock"
3. in alt branch [inStock == true], proc calls inv with "reserve(itemId)"
4. proc calls order with "confirm()"
5. in alt branch [inStock == false], proc calls order with "reject("Out of stock")"
Real-World Examples
These examples show sequence diagrams for real systems. For each diagram, trace through the arrows top-to-bottom and narrate what is happening before reading the walkthrough.
Example 1: Google Sign-In — OAuth2 Login Flow
Scenario: When you click “Sign in with Google”, three systems exchange a precise sequence of messages. This diagram shows that flow — it illustrates how return messages carry data back and why the ordering of messages matters.
Detailed description
UML sequence diagram with 3 participants (Browser, AppBackend, GoogleOAuth). Messages: B calls A with "GET /login"; A replies to B with "302 redirect to accounts.google.com"; B calls G with "GET /authorize (clientId, scope)"; G replies to B with "200 auth form"; B calls G with "POST /authorize (credentials)"; G replies to B with "302 redirect with authCode"; B calls A with "GET /callback?code=authCode"; A calls G with "POST /token (authCode, clientSecret)"; G replies to A with "accessToken"; A replies to B with "200 session cookie".
Participants
Browser
AppBackend
GoogleOAuth
Messages
1. B calls A with "GET /login"
2. A replies to B with "302 redirect to accounts.google.com"
3. B calls G with "GET /authorize (clientId, scope)"
4. G replies to B with "200 auth form"
5. B calls G with "POST /authorize (credentials)"
6. G replies to B with "302 redirect with authCode"
7. B calls A with "GET /callback?code=authCode"
8. A calls G with "POST /token (authCode, clientSecret)"
9. G replies to A with "accessToken"
10. A replies to B with "200 session cookie"
What the UML notation captures:
Three lifelines, one flow:Browser, AppBackend, and GoogleOAuth are the three participants. The browser intermediates between your app and Google — this is why OAuth feels like a redirect chain.
Solid arrows (synchronous calls): Every -> means the sender blocks and waits for a response before continuing. The browser sends a request and waits for the redirect before proceeding.
Dashed arrows (return messages): The --> arrows carry responses back — the auth code, the access token, the session cookie. Return messages always flow back to the caller.
Top-to-bottom = time: Reading vertically, you reconstruct the complete OAuth handshake in order. Swapping any two messages would break the protocol — the diagram makes those ordering dependencies visible.
Example 2: DoorDash — Placing a Food Order
Scenario: When a user submits an order, the app charges their card and notifies the restaurant. But what if the payment fails? This diagram uses an alt fragment to model both the success and failure paths explicitly.
Detailed description
UML sequence diagram with 4 participants (MobileApp, OrderService, PaymentGateway, Restaurant). Messages: app calls os with "submitOrder(items, paymentInfo)"; os calls pg with "charge(amount, card)"; pg replies to os with "chargeResult"; in alt branch [chargeResult.approved], os calls rest with "notifyNewOrder(items)"; rest replies to os with "estimatedTime"; os replies to app with "confirmed(orderId, eta)"; in alt branch [chargeResult.declined], os replies to app with "error(chargeResult.reason)".
Participants
MobileApp
OrderService
PaymentGateway
Restaurant
Combined fragments
alt branch [chargeResult.approved]
alt branch [chargeResult.declined]
Messages
1. app calls os with "submitOrder(items, paymentInfo)"
2. os calls pg with "charge(amount, card)"
3. pg replies to os with "chargeResult"
4. in alt branch [chargeResult.approved], os calls rest with "notifyNewOrder(items)"
5. rest replies to os with "estimatedTime"
6. os replies to app with "confirmed(orderId, eta)"
7. in alt branch [chargeResult.declined], os replies to app with "error(chargeResult.reason)"
What the UML notation captures:
Charge once, then branch on the response: The charge() call is issued before the alt fragment, and chargeResult is returned to OrderService. The alt then branches on the content of that response — never call payment twice. Putting the charge() inside both branches would imply a double charge attempt, which would be an architectural bug.
alt fragment (if/else): The dashed horizontal line inside the box divides the two branches. Only one branch executes at runtime. When you see alt, think if/else.
Guard conditions in [ ]:[chargeResult.approved] and [chargeResult.declined] are boolean guards — they must be mutually exclusive so exactly one branch fires.
Different paths, different participants: In the success branch, the flow continues to Restaurant. In the failure branch, it returns immediately to the app. The diagram makes both paths equally visible — no “happy path bias”.
Why alt and not opt? An opt fragment has only one branch (if, no else). Because we have two explicit outcomes — success and failure — alt is the correct choice.
Example 3: GitHub Actions — CI/CD Pipeline Trigger
Scenario: A developer pushes code, GitHub triggers a build, tests run, and deployment happens only if tests pass. This diagram uses opt for conditional deployment and a self-call for internal processing.
Detailed description
UML sequence diagram with 4 participants (Developer, GitHub, BuildService, DeployService). Messages: dev calls gh with "git push origin main"; gh calls build with "triggerBuild(commitSha)"; build calls build with "runTests()"; build replies to gh with "testResults"; in optional fragment [all tests passed], gh calls deploy with "deployToStaging(artifact)"; deploy replies to gh with "stagingUrl"; gh replies to dev with "notify(testResults)".
Participants
Developer
GitHub
BuildService
DeployService
Combined fragments
optional fragment [all tests passed]
Messages
1. dev calls gh with "git push origin main"
2. gh calls build with "triggerBuild(commitSha)"
3. build calls build with "runTests()"
4. build replies to gh with "testResults"
5. in optional fragment [all tests passed], gh calls deploy with "deployToStaging(artifact)"
6. deploy replies to gh with "stagingUrl"
7. gh replies to dev with "notify(testResults)"
What the UML notation captures:
Self-call (build -> build): A message from a lifeline back to itself models an internal call — BuildService running its own test suite. The arrow loops back to the same column.
opt fragment (if, no else): Deployment only happens if all tests pass. There is no “else” branch — on failure the flow skips the opt block and continues to the notification.
Return after the fragment:gh --> dev: notify(testResults) executes regardless of whether deployment occurred — it is outside the opt box, at the outer sequence level.
Activation ordering:build runs runTests() before returning testResults to gh. Top-to-bottom ordering guarantees tests complete before GitHub is notified.
Example 4: Uber — Real-Time Driver Matching
Scenario: When a rider requests a trip, the matching service offers the ride to drivers until one accepts. This diagram shows a loop fragment combined with an alt inside — the most powerful combination in sequence diagrams.
Detailed description
UML sequence diagram with 4 participants (RiderApp, MatchingService, DriverApp, NotificationService). Messages: rider calls match with "requestRide(location, rideType)"; in loop [no driver has accepted], match calls driver with "offerRide(request)"; driver replies to match with "response"; match calls notif with "notifyRider(driverId, eta)"; notif replies to rider with "driverAssigned(eta)".
Participants
RiderApp
MatchingService
DriverApp
NotificationService
Combined fragments
loop [no driver has accepted]
Messages
1. rider calls match with "requestRide(location, rideType)"
2. in loop [no driver has accepted], match calls driver with "offerRide(request)"
3. driver replies to match with "response"
4. match calls notif with "notifyRider(driverId, eta)"
5. notif replies to rider with "driverAssigned(eta)"
What the UML notation captures:
loop fragment: The matching service repeats the offer-cycle until a driver accepts (the loop guard [no driver has accepted] checks the response). loop models iteration — equivalent to a while loop. In practice this loop also has a timeout (e.g., a maximum number of attempts before cancellation), which would tighten the guard condition.
Offer once per iteration, branch on the response: The diagram shows a single offerRide(request) per loop iteration — the driver’s response is either accepted or declined/timeout. The loop guard then decides whether to continue. Sending the same offer twice inside an alt would mistakenly model two separate offers for what is really one driver interaction.
Flow continues after the loop: Once a driver accepts, the loop guard becomes false and execution exits, then the notification is sent. Messages outside a fragment are unconditional.
DriverApp as a participant: The driver’s mobile app is a first-class lifeline. This shows that sequence diagrams can include mobile clients, web clients, and backend services on equal footing.
Example 5: Slack — Real-Time Message Delivery
Scenario: When you send a Slack message, it is persisted, then broadcast to all subscribers of that channel. This diagram shows the fan-out delivery pattern using a loop fragment.
Detailed description
UML sequence diagram with 5 participants (SlackClient, WebSocketGateway, MessageService, NotificationService, SlackClient[*]). Messages: sender calls ws with "sendMessage(channelId, text)"; ws calls msg with "persist(channelId, text, userId)"; msg replies to ws with "messageId"; ws calls notif with "broadcastToChannel(channelId, message)"; in loop [for each online subscriber], notif calls ws with "deliver(userId, message)"; ws asynchronously messages subscriber with "messageReceived"; ws replies to sender with "ack(messageId)".
Participants
SlackClient
WebSocketGateway
MessageService
NotificationService
SlackClient[*]
Combined fragments
loop [for each online subscriber]
Messages
1. sender calls ws with "sendMessage(channelId, text)"
2. ws calls msg with "persist(channelId, text, userId)"
3. msg replies to ws with "messageId"
4. ws calls notif with "broadcastToChannel(channelId, message)"
5. in loop [for each online subscriber], notif calls ws with "deliver(userId, message)"
6. ws asynchronously messages subscriber with "messageReceived"
7. ws replies to sender with "ack(messageId)"
What the UML notation captures:
Sequence before the loop:persist and get messageId happen exactly once — before the broadcast. The diagram makes this ordering explicit: a message is saved before it is delivered to anyone.
loop for fan-out delivery: Each online subscriber receives their own delivery. The lifeline subscriber : SlackClient[*] represents the set of recipient clients (distinct from the original sender); the asynchronous arrow ->> shows the gateway pushes the message — this is server-pushed, not a return value. In a channel with 200 members, the loop body executes 200 times.
ack after the loop: The original sender receives their acknowledgment (ack(messageId)) only after the broadcast completes. This is outside the loop — it is unconditional and happens once. Note that ack returns to sender, while delivery flows to subscriber — distinguishing these two lifelines is essential to model fan-out correctly.
WebSocketGateway as the central hub: All messages flow in and out through the gateway. The diagram shows this hub topology clearly — every arrow touches ws, revealing it as the architectural bottleneck. This is a useful architectural insight visible only in the sequence diagram.
Chapter Summary
Sequence diagrams are a powerful tool to understand the dynamic, time-based behavior of a system.
Lifelines and Messages establish the basic timeline of communication.
OPT fragments handle “maybe” scenarios (if).
ALT fragments handle “either/or” scenarios (if/else).
By mastering these fragments, you can model nearly any procedural logic within an object-oriented system before writing a single line of code.
End of Chapter Exercises (Retrieval Practice)
To solidify your learning, attempt these questions without looking back at the text.
What is the key difference between an ALT fragment and an OPT fragment?
If you needed to model a user trying to enter a password 3 times before being locked out, which fragment would you use as the outer box, and which fragment would you use inside it?
Draw a simple sequence diagram (using pen and paper) of yourself ordering a book online. Include one OPT fragment representing applying a promo code.
Practice
Test your knowledge with these retrieval practice exercises. These diagrams are rendered dynamically to ensure you can recognize UML notation in any context.
UML Sequence Diagram Flashcards
Quick review of UML Sequence Diagram notation and fragments.
Difficulty:Basic
What is the difference between a synchronous and an asynchronous message arrow?
Synchronous uses a filled arrowhead; asynchronous uses an open (stick) arrowhead.
A synchronous message (filled arrowhead) means the sender waits for the receiver to finish. An asynchronous message (open arrowhead) means the sender continues immediately without waiting.
Detailed description
UML sequence diagram with 2 participants (Caller, Receiver). Messages: a calls b with "syncCall()"; b replies to a with "response"; a asynchronously messages b with "asyncNotify()".
Participants
Caller
Receiver
Messages
1. a calls b with "syncCall()"
2. b replies to a with "response"
3. a asynchronously messages b with "asyncNotify()"
Difficulty:Basic
How is a return message drawn in a sequence diagram?
A dashed line with an open arrowhead.
Return messages use dashed lines to distinguish them from call messages (which use solid lines). They are optional — include them when the return value is important to understanding the interaction.
Detailed description
UML sequence diagram with 2 participants (Client, Service). Messages: a calls b with "getData()"; b replies to a with "result".
Participants
Client
Service
Messages
1. a calls b with "getData()"
2. b replies to a with "result"
Difficulty:Intermediate
What is the difference between an opt fragment and an alt fragment?
opt = if (no else). alt = if-else with multiple branches.
An opt fragment has a single guard condition — messages execute only if the guard is true (like an if without else). An alt fragment has two or more regions separated by dashed lines, each with its own guard — exactly one region executes (like if-else or switch).
Difficulty:Basic
What does a lifeline represent, and how is it drawn?
A participant in the interaction — drawn as a box at the top with a dashed vertical line extending downward.
The box contains the participant’s name (format: objectName:ClassName or :ClassName). The dashed vertical line represents the participant’s existence over time. Time flows top-to-bottom.
Difficulty:Basic
Name the combined fragment you would use to model a for/while loop in a sequence diagram.
The loop fragment.
The loop fragment repeats the enclosed messages. It can specify bounds like loop [1, 5] (min 1, max 5 iterations) or a guard condition like loop [items remaining].
Detailed description
UML sequence diagram with 2 participants (App, Server). Messages: in loop [1, 3], a calls b with "retry()"; b replies to a with "ack()".
Participants
App
Server
Combined fragments
loop [1, 3]
Messages
1. in loop [1, 3], a calls b with "retry()"
2. b replies to a with "ack()"
Difficulty:Basic
What does an activation bar (execution specification) represent on a lifeline?
The period during which the object is actively performing an action or behavior.
Thin rectangles on a lifeline showing when an object is processing a method call. They nest when A calls B which calls C — all three carry overlapping bars — so you can see which objects are busy at any point.
Difficulty:Advanced
What is the correct naming convention for lifelines in sequence diagrams?
objectName : ClassName (e.g., myCart : ShoppingCart or : ShoppingCart for anonymous instances).
Sequence diagrams show interactions between specific object instances, not classes in general. If the object name is irrelevant, you can omit it and write just : ClassName. This distinguishes sequence diagrams from class diagrams, which model classes in general.
Difficulty:Advanced
What is the par combined fragment used for?
To model messages that execute in parallel (concurrently).
The par fragment divides the interaction into regions that execute simultaneously. This is useful for modeling multi-threaded behavior or concurrent operations. The critical fragment is related: it marks a region that cannot be interleaved by other event occurrences — the equivalent of a synchronized block.
Workout Complete!
Your Score: 0/8
Come back later to improve your recall!
UML Sequence Diagram Practice
Test your ability to read and interpret UML Sequence Diagrams.
Difficulty:Basic
What type of message is represented by a solid line with a filled (solid) arrowhead?
Detailed description
UML sequence diagram with 2 participants (Client, Server). Messages: a calls b with "request()".
Participants
Client
Server
Messages
1. a calls b with "request()"
Asynchronous messages use an open stick arrowhead. The filled arrowhead marks a call where the sender waits for the receiver to finish.
Return messages are dashed lines going back to the caller. This solid call arrow is the request, not the response.
Creation is shown with a create message and a lifeline that begins at the creation point. This arrow is a normal synchronous call.
Correct Answer:
Explanation
A solid line with a filled arrowhead is a synchronous message — the sender blocks until the receiver finishes. An asynchronous message uses an open (stick) arrowhead instead: filled means full commitment, open means fire-and-forget.
Difficulty:Basic
What does the dashed line in the diagram below represent?
Detailed description
UML sequence diagram with 2 participants (Client, Server). Messages: a calls b with "calculate()"; b replies to a with "result".
Participants
Client
Server
Messages
1. a calls b with "calculate()"
2. b replies to a with "result"
Asynchronous messages are normal message sends, usually drawn with a solid line and open arrowhead. The dashed line after a call conventionally shows a return.
Dependencies are structural relationships in class or component diagrams. Sequence diagrams use dashed return messages to show a response value or control returning.
A synchronous callback would be a new call message, not the return from the earlier calculate() call.
Correct Answer:
Explanation
A dashed line with an open arrowhead is a return message, carrying the response back to the caller. Return messages are optional — show them when the returned value matters to the interaction, omit them when a synchronous call obviously returns.
Difficulty:Basic
Which combined fragment would you use to model an if-else decision in a sequence diagram?
Detailed description
UML sequence diagram with 2 participants (Client, AuthService). Messages: c calls a with "login(user, pass)"; in alt branch [credentials valid], a replies to c with "token"; in alt branch [credentials invalid], a replies to c with "error".
Participants
Client
AuthService
Combined fragments
alt branch [credentials valid]
alt branch [credentials invalid]
Messages
1. c calls a with "login(user, pass)"
2. in alt branch [credentials valid], a replies to c with "token"
3. in alt branch [credentials invalid], a replies to c with "error"
loop models repetition. An if-else decision needs mutually exclusive alternatives, not repeated execution.
opt is for one optional block with no else branch. If there are multiple possible branches, use alt.
par models concurrent regions. It does not choose one branch based on a guard.
Correct Answer:
Explanation
alt models if-else by selecting one of several guarded branches; only one region executes. Use opt for a simple if-without-else — a single guarded block with no alternative.
Difficulty:Intermediate
Look at this diagram. How many times could the ping() message be sent?
Detailed description
UML sequence diagram with 2 participants (App, Server). Messages: app calls server with "connect()"; in loop [1, 5], app calls server with "ping()"; server replies to app with "ack()".
Participants
App
Server
Combined fragments
loop [1, 5]
Messages
1. app calls server with "connect()"
2. in loop [1, 5], app calls server with "ping()"
3. server replies to app with "ack()"
The upper bound is 5, but the lower bound is 1. The fragment may stop before 5 iterations.
0..* would suggest zero or more. The shown bounds [1, 5] require at least one iteration and at most five.
One iteration is allowed, but it is not the only allowed count. The upper bound permits more pings.
Correct Answer:
Explanation
loop [1, 5] means the enclosed messages execute between 1 and 5 times — the minimum and maximum iteration bounds. The loop [1, 5] fragment specifies a minimum of 1 and maximum of 5 iterations. The messages inside will execute between 1 and 5 times depending on conditions at runtime.
Difficulty:Intermediate
Which of the following are valid combined fragment types in UML sequence diagrams? (Select all that apply.)
alt is the UML combined fragment for alternative guarded branches. Omitting it misses the normal way to model if-else behavior.
opt is a valid combined fragment for optional execution: an if without an else.
UML uses alt and opt for conditional behavior, not an if fragment operator.
loop is valid for repeated execution, such as a for-loop or while-loop scenario.
UML does not use a try combined fragment. Exception-like or aborting behavior can be modeled with other interaction operators such as break, depending on the case.
par is valid when regions proceed in parallel or independently.
Correct Answers:
Explanation
alt, opt, loop, and par are valid UML combined fragments; there is no if or try operator. Conditional logic uses alt/opt, and exception-like aborting behavior uses the break fragment.
Difficulty:Intermediate
What does the opt fragment in this diagram mean?
Detailed description
UML sequence diagram with 2 participants (Checkout, Pricing Engine). Messages: c calls p with "calculateTotal()"; in optional fragment [hasPromoCode == true], p calls p with "applyDiscount()"; p replies to p with "discountApplied()"; p replies to c with "finalTotal()".
Participants
Checkout
Pricing Engine
Combined fragments
optional fragment [hasPromoCode == true]
Messages
1. c calls p with "calculateTotal()"
2. in optional fragment [hasPromoCode == true], p calls p with "applyDiscount()"
3. p replies to p with "discountApplied()"
4. p replies to c with "finalTotal()"
opt means optional, not guaranteed. The guard controls whether the enclosed messages happen.
There is no alternate branch here. Returning the final total happens after the optional block either way.
Repetition would use loop. opt describes one conditional execution of the enclosed messages.
Correct Answer:
Explanation
opt is an if-without-else — the discount messages execute only if hasPromoCode is true, otherwise the whole fragment is skipped. Execution then continues with the messages after the fragment regardless of the guard.
Difficulty:Basic
In UML sequence diagrams, what does time represent?
The horizontal axis separates participants. Order is read vertically from top to bottom.
Sequence diagrams are specifically for ordering interactions. The vertical placement of messages carries time order.
Right-to-left is not the time direction. Participants can be arranged left-to-right for readability, but later messages appear lower.
Correct Answer:
Explanation
Time flows top-to-bottom along the vertical axis — messages higher in the diagram happen first. The horizontal axis carries no time meaning; it just separates the participants (lifelines).
Difficulty:Basic
Which arrow style represents an asynchronous message where the sender does NOT wait for a response?
A filled arrowhead on a solid line is the usual synchronous call notation. It implies the sender waits for completion.
A dashed line with an open arrowhead is a return message. It is the response to a previous call, not a new asynchronous send.
This combines the return-message line style with the synchronous arrowhead style. It is not the standard asynchronous message notation taught here.
Correct Answer:
Explanation
An asynchronous message uses a solid line with an open (stick) arrowhead — the sender fires and continues without waiting. This contrasts with a synchronous message (filled arrowhead), where the sender blocks until the receiver finishes.
Detailed description
UML sequence diagram with 2 participants (Sender, Receiver). Messages: a asynchronously messages b with "notify()".
Participants
Sender
Receiver
Messages
1. a asynchronously messages b with "notify()"
Difficulty:Basic
What does an activation bar (thin rectangle on a lifeline) represent?
Detailed description
UML sequence diagram with 3 participants (UI, OrderService, Database). Messages: ui calls os with "placeOrder(items)"; os calls db with "saveOrder(items)"; db replies to os with "orderId"; os replies to ui with "confirmation(orderId)".
Participants
UI
OrderService
Database
Messages
1. ui calls os with "placeOrder(items)"
2. os calls db with "saveOrder(items)"
3. db replies to os with "orderId"
4. os replies to ui with "confirmation(orderId)"
Waiting idly is not what the activation bar marks. The bar shows the participant is executing or has control during that interval.
Destruction is shown with a destruction occurrence, often an X at the end of a lifeline. An activation bar is about execution.
UML activation bars do not mean a suspended state. They show an execution specification on that lifeline.
Correct Answer:
Explanation
An activation bar (execution specification) shows the period during which an object is actively processing — executing a method or waiting on a sub-call. The bars nest when one method call triggers another.
Difficulty:Advanced
What is the correct lifeline label format for an unnamed instance of class ShoppingCart?
Detailed description
UML sequence diagram with 2 participants (ShoppingCart, Checkout). Messages: sc calls ch with "submit()"; ch replies to sc with "receipt".
Participants
ShoppingCart
Checkout
Messages
1. sc calls ch with "submit()"
2. ch replies to sc with "receipt"
ShoppingCart alone names the classifier, not an unnamed instance. The colon is what indicates an instance of that class.
cart: ShoppingCart is a named instance. The question asks for an unnamed instance, so the object name before the colon is omitted.
class ShoppingCart is class-declaration style, not lifeline-label style. Sequence lifelines model participants in one interaction.
Correct Answer:
Explanation
An unnamed instance is written : ClassName — the leading colon is what marks it as an instance. The full form is objectName : ClassName; dropping the name still requires the colon, because lifelines model specific object instances, not classes in general.
Difficulty:Intermediate
Given this Java code, which sequence diagram element represents the new Payment(amount) call?
java public void makePayment(int amount) {
Payment p = new Payment(amount);
p.authorize();
}
Detailed description
UML sequence diagram with 2 participants (Checkout, Payment). Messages: ch replies to p with "<<create>>"; ch calls p with "authorize()"; p replies to ch with "authorized".
Participants
Checkout
Payment
Messages
1. ch replies to p with "<<create>>"
2. ch calls p with "authorize()"
3. p replies to ch with "authorized"
The object does not exist before the constructor call, so its lifeline should begin at the creation point rather than at the top as an existing participant.
A return message would show a response after a call. The constructor call is the creation event itself.
A loop fragment is for repeated interaction. Creating one object once is modeled with a create message, not repetition.
Correct Answer:
Explanation
A constructor call (new) becomes a create message — the new object’s lifeline begins at the point of creation, not at the top. Pre-existing objects appear at the top of the diagram; a created object’s box drops in at the vertical position where it is instantiated.
Difficulty:Advanced
A sequence diagram and a class diagram are drawn for the same system. An arrow in the sequence diagram shows order -> inventory: checkStock(itemId). What must be true in the class diagram?
A dependency or association may be needed depending on how order reaches inventory, but the unavoidable consistency rule is that the receiver can handle the message.
Inventory could be a class or interface, but Order realizing Inventory would mean Order implements Inventory’s contract. That is not implied by sending a message to inventory.
An attribute is one possible design if Order stores a reference, but the sequence message alone does not force that. The receiver still needs the operation being called.
Correct Answer:
Explanation
Every message arrow must correspond to a method on the receiving object’s class (or a superclass), so Inventory needs a checkStock(itemId) method. Sequence and class diagrams of the same system must stay consistent in method names, parameters, and return types.
Workout Complete!
Your Score: 0/12
Pedagogical Tip: If you find these challenging, it’s a good sign! Effortful retrieval is exactly what builds durable mental models. Try coming back to these tomorrow to benefit from spacing and interleaving.
Interactive Tutorials
Master UML sequence diagrams by writing code that matches target diagrams in our interactive tutorials:
Cookie & Privacy Notice:
This site stores a few preferences and your progress locally in your browser
(cookies and localStorage) so it works the way you left it.
Nothing is sent to or stored on any external server, and this site does not
sell, share, or disclose any user data to third parties.
View & manage your data →