15.4 Basic Sequence Diagram Notation
Lifeline Boxes and Lifelines
In contrast to communication diagrams, in sequence diagrams the lifeline boxes include a vertical line extending below themthese are the actual lifelines. Although virtually all UML examples show the lifeline as dashed (because of UML 1 influence), in fact the UML 2 specification says it may be solid or dashed.
Note
lifeline boxes p. 226
Messages
Each (typical synchronous) message between objects is represented with a message expression on a filled-arrowed [3] solid line between the vertical lifelines (see Figure 15.7). The time ordering is organized from top to bottom of lifelines.
Figure 15.7 Messages and focus of control with execution specification bar.
In the example of Figure 15.7 the starting message is called a found message in the UML, shown with an opening solid ball; it implies the sender will not be specified, is not known, or that the message is coming from a random source. However, by convention a team or tool may ignore showing this, and instead use a regular message line without the ball, intending by convention it is a found message. [4]
Focus of Control and Execution Specification Bars
As illustrated in Figure 15.7, sequence diagrams may also show the focus of control (informally, in a regular blocking call, the operation is on the call stack) using an execution specification bar (previously called an activation bar or simply an activation in UML 1). The bar is optional.
Guideline: Drawing the bar is more common (and often automatic) when using a UML CASE tool, and less common when wall sketching.
Illustrating Reply or Returns
There are two ways to show the return result from a message:
-
Using the message syntax returnVar = message(parameter).
-
Using a reply (or return) message line at the end of an activation bar.
Both are common in practice. I prefer the first approach when sketching, as it's less effort. If the reply line is used, the line is normally labelled with an arbitrary description of the returning value. See Figure 15.8.
Figure 15.8 Two ways to show a return result from a message.
Messages to "self" or "this"
You can show a message being sent from an object to itself by using a nested activation bar (see Figure 15.9).
Figure 15.9 Messages to "this."
Creation of Instances
Object creation notation is shown in Figure 15.10. Note the UML-mandated dashed line. [5] The arrow is filled if it's a regular synchronous message (such as implying invoking a Java constructor), or open (stick arrow) if an asynchronous call. The message name create is not requiredanything is legalbut it's a UML idiom.
Figure 15.10 Instance creation and object lifelines.
The typical interpretation (in languages such as Java or C#) of a create message on a dashed line with a filled arrow is "invoke the new operator and call the constructor".
Object Lifelines and Object Destruction
In some circumstances it is desirable to show explicit destruction of an object. For example, when using C++ which does not have automatic garbage collection, or when you want to especially indicate an object is no longer usable (such as a closed database connection). The UML lifeline notation provides a way to express this destruction (see Figure 15.11).
Figure 15.11 Object destruction.
Diagram Frames in UML Sequence Diagrams
To support conditional and looping constructs (among many other things), the UML uses frames. [6] Frames are regions or fragments of the diagrams; they have an operator or label (such as loop) and a guard [7] (conditional clause). See Figure 15.12.
Figure 15.12 Example UML frame.
The following table summarizes some common frame operators:
Frame Operator |
Meaning |
---|---|
alt |
Alternative fragment for mutual exclusion conditional logic expressed in the guards. |
loop |
Loop fragment while guard is true. Can also write loop(n) to indicate looping n times. There is discussion that the specification will be enhanced to define a FOR loop, such as loop(i, 1, 10) |
opt |
Optional fragment that executes if guard is true. |
par |
Parallel fragments that execute in parallel. |
region |
Critical region within which only one thread can run. |
Looping
The LOOP frame notation to show looping is shown in Figure 15.12.
Conditional Messages
An OPT frame is placed around one or more messages. Notice that the guard is placed over the related lifeline. See Figure 15.13.
Figure 15.13 A conditional message.
Conditional Messages in UML 1.x StyleStill Useful?
The UML 2.x notation to show a single conditional message is heavyweight, requiring an entire OPT frame box around one message (see Figure 15.13). The older UML 1.x notation for single conditional messages in sequence diagrams is not legal in UML 2, but so simple that especially when sketching it will probably be popular for years to come. See Figure 15.14.
Figure 15.14 A conditional message in UML 1.x notationa simple style.
Guideline: Use UML 1 style only for simple single messages when sketching.
Mutually Exclusive Conditional Messages
An ALT frame is placed around the mutually exclusive alternatives. See Figure 15.15.
Figure 15.15 Mutually exclusive conditional messages.
Iteration Over a Collection
A common algorithm is to iterate over all members of a collection (such as a list or map), sending the same message to each. Often, some kind of iterator object is ultimately used, such as an implementation of java.util.Iterator or a C++ standard library iterator, although in the sequence diagram that low-level "mechanism" need not be shown in the interest of brevity or abstraction.
At the time of this writing, the UML specification did not (and may never) have an official idiom for this case. Two alternatives are shownreviewed with the leader of the UML 2 interaction specificationin Figure 15.16 and Figure 15.17.
Figure 15.16 Iteration over a collection using relatively explicit notation.
Figure 15.17 Iteration over a collection leaving things more implicit.
Note the selector expression lineItems[i] in the lifeline of Figure 15.16. The selector expression is used to select one object from a group. Lifeline participants should represent one object, not a collection.
In Java, for example, the following code listing is a possible implementation that maps the explicit use of the incrementing variable i in Figure 15.16 to an idiomatic solution in Java, using its enhanced for statement (C# has the same).
public class Sale { private List<SalesLineItem> lineItems = new ArrayList<SalesLineItem>(); public Money getTotal() { Money total = new Money(); Money subtotal = null; for ( SalesLineItem lineItem : lineItems ) { subtotal = lineItem.getSubtotal(); total.add( subtotal ); } return total; } // . . }
Another variation is shown in Figure 15.17; the intent is the same, but details are excluded. A team or tool could agree on this simple style by convention to imply iteration over all the collection elements. [8]
Nesting of Frames
Frames can be nested. See Figure 15.18.
Figure 15.18 Nesting of frames.
How to Relate Interaction Diagrams?
Figure 15.19 illustrates probably better than words. An interaction occurrence (also called an interaction use) is a reference to an interaction within another interaction. It is useful, for example, when you want to simplify a diagram and factor out a portion into another diagram, or there is a reusable interaction occurrence. UML tools take advantage of them, because of their usefulness in relating and linking diagrams.
Figure 15.19 Example interaction occurrence, sd and ref frames.
They are created with two related frames:
-
a frame around an entire sequence diagram [9] , labeled with the tag sd and a name, such as AuthenticateUser
-
a frame tagged ref, called a reference, that refers to another named sequence diagram; it is the actual interaction occurrence
Interaction overview diagrams also contain a set of reference frames (interaction occurrences). These diagrams organized references into a larger structure of logic and process flow.
Guideline: Any sequence diagram can be surrounded with an sd frame, to name it. Frame and name one when you want to refer to it using a ref frame.
Messages to Classes to Invoke Static (or Class) Methods
You can show class or static method calls by using a lifeline box label that indicates the receiving object is a class, or more precisely, an instance of a metaclass (see Figure 15.20).
Figure 15.20 Invoking class or static methods; showing a class object as an instance of a metaclass.
What do I mean? For example, in Java and Smalltalk, all classes are conceptually or literally instances of class Class; in .NET classes are instances of class Type. The classes Class and Type are metaclasses, which means their instances are themselves classes. A specific class, such as class Calendar, is itself an instance of class Class. Thus, class Calendar is an instance of a metaclass! It may help to drink some beer before trying to understand this.
In code, a likely implementation is:
public class Foo { public void doX() { // static method call on class Calendar Locale[] locales = Calendar.getAvailableLocales(); // . . } // . . }
Polymorphic Messages and Cases
Polymorphism is fundamental to OO design. How to show it in a sequence diagram? That's a common UML question. One approach is to use multiple sequence diagramsone that shows the polymorphic message to the abstract superclass or interface object, and then separate sequence diagrams detailing each polymorphic case, each starting with a found polymorphic message. Figure 15.21 illustrates.
Figure 15.21 An approach to modeling polymorphic cases in sequence diagrams.
Asynchronous and Synchronous Calls
An asynchronous message call does not wait for a response; it doesn't block. They are used in multi-threaded environments such as .NET and Java so that new threads of execution can be created and initiated. In Java, for example, you may think of the Thread.start or Runnable.run (called by Thread.start) message as the asynchronous starting point to initiate execution on a new thread.
The UML notation for asynchronous calls is a stick arrow message; regular synchronous (blocking) calls are shown with a filled arrow (see Figure 15.22).
Figure 15.22 Asynchronous calls and active objects.
Guideline
This arrow difference is subtle. And when wall sketching UML, it is common to use a stick arrow to mean a synchronous call because it's easier to draw. Therefore, when reading a UML interaction diagram don't assume the shape of the arrow is correct!
An object such as the Clock in Figure 15.22 is also known as an active objecteach instance runs on and controls its own thread of execution. In the UML, it may be shown with double vertical lines on the left and right sides of the lifeline box. The same notation is used for an active class whose instances are active objects.
Note
active class p. 269
In Java, a likely implementation for Figure 15.22 follows. Notice that the Thread object in the code is excluded from the UML diagram, because it is simply a consistent "overhead" mechanism to realize an asynchronous call in Java.
public class ClockStarter { public void startClock() { Thread t = new Thread( new Clock() ); t.start(); // asynchronous call to the 'run' method on the Clock System.runFinalization(); // example follow-on message } // . . } // objects should implement the Runnable interface // in Java to be used on new threads public class Clock implements Runnable { public void run() { while ( true ) // loop forever on own thread { // . . } } // . . }