Topic 9
Sequence Diagrams
Introduction
Having linked the use-cases to the domain model classes with design-level use case texts, the next stage is to move to a more detailed design, in which we work out what methods might need to be implemented, which classes they belong to and what order each method should be called. The sequence diagram allows us to do this: sequence diagrams show all the components in the system and their interactions (in the form of method calls), focusing on the order (sequence) in which they are called. Once a sequence diagram is completed, the methods shown on it can be used to enhance or correct the class diagram, to produce a finalised, accurate class diagram from which coding can begin.
What we have to do
Our aim is to convert the design-level use case text into the sequence diagram. We will go through the process by looking at our first design-level use case text from the previous topic (Enrol a Student) as an example:
Design-level use case text: enrol a student
| Step | Actor action | System response |
|---|---|---|
| 1 | The use case begins when the admin staff selects to enrol a new student. | - |
| 2 | - | The UI prompts the user for the student details (name, address, date of birth, course) |
| 3 | The user enters the details specified in step 2. | - |
| 4 | - | The UI checks validity of details, e.g. date of birth is sensible |
| 5 | - | The University object allocates student ID for new student, using the highest ID so far plus one |
| 6 | - | A Student object is created and added to the list of Students in the University object |
| 7 | - | The UI confirms enrolment is successful. |
First - work out what methods are needed
Before we draw the sequence diagram, it helps to clearly identify the methods which will be needed to implement the use case. We can do this by analysing our design-level sequence diagram still further.
Here is an example of how to do this from the "enrol a student" design-level use case text shown above. As we saw above, the most interesting steps are step 5 and 6 because they involve objects of the domain model classes University and Student. We can think about these steps in a bit more detail in order to work out what methods might be needed.
- We first need to allocate a student ID, using the existing highest ID plus one. As we have seen, this is the responsibility of the
University. So it follows logically that we could allocate a method -allocateStudentId()- for this functionality, and place it in theUniversityclass. - We then need to create a student object using that ID, and add it to the list of students. Again, it follows logically that we need a new method,
addNewStudent(), also insideUniversity, which takes aStudentobject and adds it to theUniversity. - So we end up with two methods of
Universityto implement this use case. These will be shown as messages on the sequence diagram.
Secondly - draw the sequence diagram
We then draw the sequence diagram by going through the use case and showing the interactions between the components of the system, including the actor, UI and domain model classes. Two components interact if they communicate with each other. What do we mean when we say components communicate with each other?
- An actor communicates with the UI by pressing buttons, filling in text fields, and so on.
- The UI communicates with an actor by displaying information.
- A class communicates with another class by calling a method of the other class. In response, the other class might return data.
Before drawing the sequence diagram for "enrol student", we need to understand sequence diagram notation.
Sequence diagram notation
- Sequence diagrams show the communication between the components of the system in the correct sequence (hence the name)
- Each component (actor, class) is shown as a vertical lifeline representing the time span in which it is active
- For example, in the sequence diagram below there are lifelines for "admin staff" (actor),
GUI,UniversityandStudent
- For example, in the sequence diagram below there are lifelines for "admin staff" (actor),
- When a component communicates with another, we say that the component (actor, UI or class) sends the other component a message
- These are shown as solid arrows
- In code, this translates to class A calling a method of class B
- The arrow shows the direction of the message
- Sometimes one class sends itself a message (a self-call) - for example
checkDetails()on the sequence diagram below - Return values (return messages) are shown by a dotted line

Overall, the sequence diagram shows how the control flows from one component to another (e.g. actor to UI, UI to class, or class to another class). A given component is in control when a method of that component is running (or, in the case of an actor, the actor is interacting with the UI). A vertical box on a given lifeline is known as an activation box and represents a continuous period of control in one component, for example, a method.
Full explanation of sequence diagram for Enrol Student
- The control starts with the admin staff, when they choose to add a new student (step 1).
- The control then shifts to the UI, which prompts the user to enter the student details (step 2).
- The control then shifts back to the admin staff, who enters the student details (step 3).
- The control then shifts back to the UI, which receives the student details and validates them (step 4). Validation does not require the use of domain model classes, so we write it as a self-call (see above): the UI can do it with its own method, which might be called
validateDetails(). - The student then needs to be created, which the UI cannot do on its own. It needs to call upon the domain model classes to do this. This corresponds to the UI calling methods of the domain model classes. In our initial analysis, above, we worked out the two methods we need, both in the
Universityclass:allocateStudentId()to allocate a student ID, andaddNewStudent()to add a student. - So the flow of control transfers to the
Universityfor step 5, to allocate a new student ID. This involves the UI calling theallocateStudentId()method of theUniversitywhich then returns an ID. - The step to return the ID is clearly shown in the sequence diagram. It is shown as a return message (dotted line, going the other way)
- We then need to create a new student and add it to the list: as we saw above, this is done with the
addNewStudent()method. This method will perform both tasks. It will need the student ID allocated in the previous step, so we pass it in as a parameter. - Finally the UI displays a confirmation message (e.g. a dialog box). This is represented by a message sent back to the admin staff, so the flow of control is transferred back to the admin staff (who can then continue to use the application).
Example 2 - Edit student details
We will now go through the second use case in a similar way. Firstly, here is the design-level use case text from the previous topic:
| Step | Actor action | System response |
|---|---|---|
| 1 | The use case begins when the admin staff selects to edit the student details | - |
| 2 | - | The UI prompts the user for the student ID |
| 3 | The member of staff enters the student ID. | - |
| 4 | - | The University object finds the Student object with that ID |
| 5 | - | The UI displays details of that student in editable text boxes |
| 6 | The admin staff changes the details. | - |
| 7 | - | The UI checks that the new details are valid (e.g. no blank strings) |
| 8 | - | The details of the found Student object are updated |
| 9 | - | The UI displays a confirmation message to the user. |
Once again, the first step, before we draw up the sequence diagram, is to identify what methods we need in our domain model classes. We have already seen, in the design-level use-case text, that steps 4 and 8 involve the domain model classes. Firstly in step 4, the University finds the Student with that ID. Hopefully, it's fairly clear what method would be needed here. We'd need a method within University to loop through the list of students, and return the Student with the correct ID. So we could define a method called findStudentById() which takes a student ID as a parameter and returns a Student.
Step 8 in this use case is even more straightforward, we just need to update the details of the found Student. We could define a method of Student which takes the new details as parameters and updates the properties to those new values. This method could simply be called updateDetails().
So we could have a sequence diagram like this:

- In step 1 the control is with the admin staff: the admin staff selects the option to edit the student details.
- The flow of control then shifts to the UI in step 2: the UI displays a form to allow the admin staff to enter the student ID.
- The flow of control then shifts back to the admin staff in step 3, and they enter an ID.
- The flow of control shifts back to the UI (the admin staff can only interact with the UI!) in step 4, but the UI then immediately transfers control to the
Universityto find the student with that ID, using thefindStudentById()method we discussed above. - The
Universityreturns theStudentto the UI by means of a return message, the flow of control returns to the UI, and the UI displays the student details in editable text boxes (step 5). - The flow of control then shifts back to the admin staff, who changes the appropriate details, in step 6.
- The flow of control then shifts to the UI once again in step 7, which validates the details the user entered.
- In step 8, the flow of control shifts to the
Studentthat we found in step 4. The UI sends the new details to theStudentobject, which updates its details to the new ones entered by the admin staff. - The flow of control returns to the UI in step 9, which displays a confirmation message in a dialog box, which is displayed to the admin staff, with the flow of control finishing with the admin staff so that they can then dismiss the dialog box.
- Note that the
Studentlifeline is labelledfoundStudent: Student. This is because it represents one specific student,foundStudent(the student we found), rather than students in general.
Alternative courses of action on a sequence diagram
You can also show alternative courses of action on a sequence diagram. This is done by means of a UML frame. This has a label (alt for alternative courses of action) together with two or more sections, each representing an alternative course of action, and separated by a dotted line. Each section is annotated with the condition which must hold true for that course of action to run. Here is an example:
Preparing a sequence diagram in diagrams.net
Please see this blog article for more detail on preparing a sequence diagram in diagrams.net.
Improving the design
You will note that much of the flow of control is in the GUI in the examples above, particularly the "add student" sequence diagram. The GUI sends an allocateStudentId() message to the University, creates a Student and then adds that Student to the University.
Would it not be better, for reusability, to move that whole sequence into the University, so that the entire enrolment process can be reused in a non-GUI application, e.g. a console application, or an application with a different GUI, e.g. a web or Android application?
The sequence diagram below re-implements the design to do this.

Exercises
We are returning now to the live music venue scenario from weeks 4 and 5, where we produced use case texts for "add an event" and "book an event". These use cases are shown below, as well as a class diagram. They have been modified slightly from the originals in weeks 4 and 5.
Class diagram

Design-level use-case texts (repeated from Topic 5 with slight modifications)
Add an event
| Step | Actor action | System response |
|---|---|---|
| 1 | The use case begins when the venue staff selects to add a new event. | - |
| 2 | - | The UI prompts the user for the event details (name, type, date, time) |
| 3 | The venue staff enters the details specified in step 2. | - |
| 4 | - | The UI checks validity of details, e.g. date/time is not in the past, fields are not blank |
| 5 | - | The Venue checks that there is no event already present at that date and time |
| 6 | - | An Event object is created, and added to the Venue object |
| 7 | - | The UI confirms successful addition |
Book an event
Assumption: the user is already logged in, and there is a Customer object available, representing the currently logged-in user.
| Step | Actor action | System response |
|---|---|---|
| 1 | The use case begins when the customer selects to book an event. | - |
| 2 | - | The UI prompts the user for the event name. |
| 3 | The customer enters the event name. | - |
| 4 | - | The UI checks event name is not blank |
| 5 | - | The Venue searches for Event objects with that name |
| 6 | - | The UI displays details of matching Event objects |
| 7 | Customer chooses event and enters number of people they would like to book for | - |
| 8 | - | The UI checks input is a valid number |
| 9 | - | The Venue object checks the venue capacity and compares it to the number of people booked already for the event, provided by the Event object, plus the number of people the user wishes to book for |
| 10 | - | The Event object allocates a booking ID and creates a Booking object containing the selected Event and current Customer. |
| 11 | - | The Booking object is added to the found Event and the current Customer. |
| 12 | - | The UI shows the booking details to the customer |
Exercise 1
Answer to exercise 1
Add an event:
- Step 3: none (user interaction)
- Step 4:
UI.checkValidityOfDetails(name, type, date, time) - Step 5:
Venue.checkEventExists(date, time) - Step 6:
Venue.addEvent(event) - Step 7: none (confirmation to user is a simple task, doesn't really need its own method)
Book an event:
- Step 3: none (user interaction)
- Step 4:
UI.checkEventName(name)or none (simple task) - Step 5:
Venue.findEventsByName(name) - Step 6:
UI.displayEventDetails(eventList) - Step 7: none (user interaction)
- Step 8:
UI.checkInputIsNumber()or none (simple task) - Step 9:
Venue.checkAvailability(nPeople, selectedEvent) - Step 10:
Event.allocateBookingId()as shown below - Step 11:
Event.addBooking(booking)andCustomer.addBooking(booking) - Step 12: none (confirmation to user is a simple task, doesn't really need its own method)