Newer
Older
labs / tiddlers / content / review / sequence-diagrams / _Review_Sequence Diagrams.tid
tags: review diagrams toc
title: /Review/Diagrams/Sequence Diagrams
type: text/vnd.tiddlywiki

\rules except dash

This is the sequence diagram tutorial from INFO201.

You can use VS Code in the Linux lab to create a new file with the extension `.pu`, or one of the various online PlantUML editors.

!PlantUML Sequence Diagram Documentation
http://plantuml.com/sequence-diagram

!Conventions in this Tutorial

<mark style="background:lime">Green highlighting shows that code has been added since the last example.</mark>

<mark style="background:aqua">Blue highlighting is code that has changed since the last example.</mark>

<mark style="background:fuchsia">Pink highlighting shows that code has been removed (or moved elsewhere) since the last example.</mark>

You should incrementally change the code as shown so that you can see the effect of each modification.

If you get totally lost you can click the diagram to open it in PlantText.

!Simple Example
The simplest example looks like:

```
@startuml
A -> B : do stuff
@enduml
```

[[plantuml[
@startuml
A -> B : do stuff
@enduml
]]]

`A` and `B`  are both //participants// (which would usually represent Java classes) and //do stuff// is a message (usually a method call) from `A` to `B`.

The footer boxes are just clutter, and the default arrows make it hard to see the difference between the different forms of messages, so we will usually put PlantUML into Strict UML mode:

<pre>@startuml
<mark style="background:lime">' use strict UML mode
skinparam style strictuml</mark>

A -> B : do stuff
@enduml
</pre>

[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

A -> B : do stuff
@enduml
]]]

!Method Call with Return
<pre>@startuml
' use strict UML mode
skinparam style strictuml

A -> B : <mark style="background:aqua">getName()</mark>
<mark style="background:lime">return name</mark>
@enduml
</pre>


[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

A -> B : getName()
return name
@enduml
]]]

This represents `A` calling the `getName()` method on `B`, and `B` returning a `name` to `A`.

Solid lines represent method calls, and dashed lines represent the response to calling those methods.

!Participants
Our participants are a bit boring.  Let's beef them up a bit:

<pre>@startuml
' use strict UML mode
skinparam style strictuml

<mark style="background:lime">participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "Book" as book &lt;&lt;domain&gt;&gt;</mark>

<mark style="background:aqua">editor -> book</mark> : getName()
<mark style="background:aqua">return name</mark>
@enduml
</pre>

[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

participant "BookEditor" as editor <<form>>
participant "Book" as book <<domain>>

editor -> book : getName()
return name
@enduml
]]]

The names in the speech marks are independent of the alias (the bits defined by the `as`).  This is handy for large diagrams because it means that we can change the displayed name of a participant without needing to change all references in the source code.  We can also use much shorter names for the aliases which makes referring to the participants much easier.

The stereotypes (the bits in the `<< >>`) are additional information that describe the type or role of a class.  They are a handy way of adding additional information about a class particularly if it is not that obvious what role the class plays from the class name alone.  Note that stereotypes are optional, but handy, so we will use them for most classes.

! Self Calls
We can show an object performing internal processing, or making calls on itself using a self-call:
<pre>@startuml
' use strict UML mode
skinparam style strictuml

participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "Book" as book &lt;&lt;domain&gt;&gt;

<mark style="background:aqua">' self call
editor -> editor : getText() </mark>
@enduml
</pre>
[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

participant "BookEditor" as editor <<form>>
participant "Book" as book <<domain>>

' self-call
editor -> editor : getText()

@enduml
]]]

!Variables and Parameters
Here is how to show variables and parameters:

<pre>@startuml
' use strict UML mode
skinparam style strictuml

participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "Book" as book &lt;&lt;domain&gt;&gt;

' get the author from the text component
editor -> editor : getText() <mark style="background:aqua">: author</mark>

<mark style="background:lime">' set the author field in the book
editor -> book : setAuthor(author)</mark>

@enduml
</pre>

[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

participant "BookEditor" as editor <<form>>
participant "Book" as book <<domain>>

' get the author from the relevant text component
editor -> editor : getText() <color red>: author</color>

' set the author field in the book
editor -> book : setAuthor(<color red>author</color>)

@enduml
]]]
The `getText` call introduces a variable (`author`) that is then passed to the book as a parameter in the `setAuthor` call.

Note that we will sometimes used a dashed line for these self-calls that return values since the call and response are combined &mdash; using the dashed line makes it more obvious that the call is returning something important:

<pre>@startuml
' use strict UML mode
skinparam style strictuml

participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "Book" as book &lt;&lt;domain&gt;&gt;

' get the author from the text component
editor <mark style="background:cyan">--></mark> editor : getText(): author

' set the author field in the book
editor -> book : setAuthor(author)

@enduml
</pre>

[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

participant "BookEditor" as editor <<form>>
participant "Book" as book <<domain>>

' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book : setAuthor(author)

@enduml
]]]

!Actors
We can show users interacting with the system using an `actor`:

<pre>@startuml
' use strict UML mode
skinparam style strictuml

<mark style="background:lime">actor "User" as user</mark>
participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "Book" as book &lt;&lt;domain&gt;&gt;

<mark style="background:lime">' user enters book details and clicks the save button
user -> editor: enters book details
user -> editor : clicks save button</mark>

' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book : setAuthor(author)

@enduml
</pre>


[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor <<form>>
participant "Book" as book <<domain>>

' user enters book details and clicks the save book button
user -> editor: enters book details
user -> editor : clicks save button

' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book : setAuthor(author)

@enduml
]]]

!Activation Bars
Activation bars show when an object is active.  This will often be as a result of a method call on the object.  Activation bars can be helpful to show where a method call finishes and ends, and generally make the diagram easier to understand:

<pre>@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "Book" as book &lt;&lt;domain&gt;&gt;

' user enters book details and clicks the save button
user -> editor<mark style="background:aqua">++</mark> : enters book details
<mark style="background:lime">editor--</mark>

user -> editor<mark style="background:aqua">++</mark> : clicks save button

' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book<mark style="background:aqua">++</mark> : setText(author)
<mark style="background:lime">book--

editor--</mark>
@enduml
</pre>

[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor <<form>>
participant "Book" as book <<domain>>

' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book++ : setAuthor(author)
book--
editor--

@enduml
]]]

You use `++` and `--` to control the activation bars on an object.

A `return` will also deactivate an object.

!Object Construction
We can show an object being created as follows:

<pre>@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "Book" as book &lt;&lt;domain&gt;&gt;

' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

' get the author from the relevant text component
editor --> editor : getText() : author

<mark style="background:lime">' construct the book object
create book
editor -> book : &lt;&lt;construct&gt;&gt;</mark>

' set the author field in the book
editor -> book++ : setAuthor(author)
editor--
@enduml
</pre>

[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor <<form>>
participant "Book" as book <<domain>>

' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

' get the author from the relevant text component
editor --> editor : getText() : author

create book
editor -> book : <<construct>>

' set the author field in the book
editor -> book++ : setAuthor(author)
book--
editor--

@enduml
]]]

If we wanted to pass the details into the Book constructor instead of using the set method:

<pre>@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "Book" as book &lt;&lt;domain&gt;&gt;

' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

' get the author from the relevant text component
editor --> editor : getText() : author

create book
editor -> book : <mark style="background:aqua">&lt;&lt;construct(author)&gt;&gt;</mark>

<mark style="background:fuchsia">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</mark>

@enduml
</pre>

[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor <<form>>


' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

' get the author from the relevant text component
editor --> editor : getText() : author

create "Book" as book <<domain>>
editor -> book : <<construct<color red>(author)</color>>>
@enduml
]]]

! Variables and Construction
We will usually do something with an object when we create it, so we need a variable name for representing the constructed object:

<pre>@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "<mark style="background:aqua">book: </mark>Book" as book &lt;&lt;domain&gt;&gt;

' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

create book
<mark style="background:aqua">editor -> book : &lt;&lt;construct&gt;&gt;</mark>

<mark style="background:lime">' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book++ : setAuthor(author)
book--

' create a DAO
create "BookListDAO" as dao &lt;&lt;DAO&gt;&gt;
editor -> dao : &lt;&lt;construct&gt;&gt;

' save book
editor -> dao++ : save(book)
dao--
editor--</mark>
@enduml
</pre>


[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "BookEditor" as editor <<form>>
participant "<color:red>book : </color>Book" as book <<domain>>
participant "BookListDAO" as dao <<DAO>>

' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

create book
editor -> book : <<construct>>

' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book++ : setAuthor(author)
book--

' create a DAO
create dao
editor -> dao : <<construct>>

' save book
editor -> dao++ : save(<color red>book</color>)
dao--
editor--
@enduml
]]]

!Object Destruction
We sometimes want to show when an object is destroyed, or at least no longer active.  This is useful for showing when a form is no longer being displayed on the screen.  If you have a main menu that creates other forms in response to the user clicking buttons, then destroying one of those other forms would imply that the user is back at the main menu again, and can longer interact with the destroyed form.

<pre>@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
<mark style="background:lime">participant "MainMenu" as menu <<form>></mark>
participant "BookEditor" as editor &lt;&lt;form&gt;&gt;
participant "book : Book" as book &lt;&lt;domain&gt;&gt;

<mark style="background:lime">'user clicks add new book button
user -> menu++: click 'Add New Book'
create editor
menu -> editor : &lt;&lt;construct&gt;&gt;</mark>

' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

create book
editor -> book : &lt;&lt;construct&gt;&gt;

' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book++ : setAuthor(author)
book--

' create a DAO
create "BookListDAO" as dao &lt;&lt;DAO&gt;&gt;
editor -> dao : &lt;&lt;construct&gt;&gt;

' save book
editor -> dao++ : save(book)
dao--
editor--

<mark style="background:lime">destroy editor</mark>

@enduml
</pre>


[[plantuml[
@startuml
' use strict UML mode
skinparam style strictuml

actor "User" as user
participant "MainMenu" as menu <<form>>
participant "BookEditor" as editor <<form>>
participant "book : Book" as book <<domain>>
participant "BookListDAO" as dao <<DAO>>

'user clicks add new book button
user -> menu++: click 'Add New Book'
create editor
menu -> editor : <<construct>>

' user enters book details and clicks the save book button
user -> editor++ : enters book details
editor--

user -> editor++ : clicks save button

create book
editor -> book : <<construct>>

' get the author from the relevant text component
editor --> editor : getText() : author

' set the author field in the book
editor -> book++ : setAuthor(author)
book--

' create a DAO
create dao
editor -> dao : <<construct>>

' save book
editor -> dao++ : save(book)
dao--
editor--

destroy editor

@enduml
]]]

!Level of Detail
We don't want a one-to-one mapping between diagram elements and source code.  That would produce a messy diagram that doesn't help us much.  What we are aiming for is to see the most important bits of the system, particularly the interaction between the objects.  It is a bit of a balancing act &mdash; too much detail results in a diagram that is effectively unreadable, and too little results in a diagram that is not a useful representation of the system.

We want to show how the classes and methods that appear in the class diagrams are used to complete a particular use case.  It is the interactions between the classes and the method calls that we want to see in a sequence diagram.  If a programmer is given accurate domain and system model class diagrams, and a sequence diagram for a use case, then there should be just enough detail in the diagram to show the programmer how to use the classes in the class diagrams to implement the use case, and no more detail than that.

Note:  Normally we wouldn't bother showing getter and setter calls like we have in this tutorial.  We wanted to keep it simple, and use something that you might have seen before if you have done some basic java programming.