As I explained in my introductory column, sequence diagramming is used to depict the internal behavior of a system over time. Because system behavior is the result of objects sending messages to each other, sequence diagrams plot the course of those messages as they move from object to object. Ultimately, sequence diagrams are maps of interaction. In the previous installment, we created a fairly simple map, although we depicted numerous interactions. This time, we'll dig in a little deeper, with a look at the two forms of sequence diagrams specified by the UML. The two forms are generic and instance. Let's start by considering the proper application of each form.
Sequence diagrams are used to depict two different types of interaction among objects. One type of interaction is the must interaction, in which object A must send a particular message to object B. The other type of interaction is the may interaction, in which object A may (but does not have to) send a particular message to object B. The two forms of sequence diagram depict these two different types of interaction. The generic form depicts must interactions and the instance form depicts may interactions.
The generic form of a sequence diagram describes the interaction of classes as the result of an initial stimulus. The generic form documents all of the interactions that could result from the initial stimulus. Both success and failure conditions are part of this type of diagram, as are loops, conditions, and branches.
A generic sequence diagram contains only a class name in each box along the horizontal axis, as seen in Figure 1. The idea here is that the object behind the interaction is anonymous and any object of that class could take part in the interaction. Therefore, all of the paths must be explicitly modeled. In a generic sequence diagram, object A must send one of the messages in the model to object B.
Figure 1. A generic sequence diagram

The second form of sequence diagram is the instance form. An instance sequence diagram describes a single possible exchange of messages between two instances. Such a diagram will contain a variable name and its class type in the boxes along the horizontal axis, as seen in Figure 2. This form does not include the loops, conditions, or branches found in the generic form. In the actual flow of control in the system, certain assertions made in the course of the interaction may be found to be false. If an assertion is found to be false, any messages within the instance sequence diagram are void and the scenario will not occur. The instance sequence diagram describes a single scenario that may or may not occur.
Figure 2. An instance sequence diagram

Instance sequence diagrams are best for modeling individual scenarios during the analysis phases of the software development life cycle. A generic sequence diagram can model an entire use case consisting of multiple scenarios. Other types of activities -- such as modeling the protocol used between subsystems or frameworks and their ensembles -- can use either form, depending on where the components are in the software development life cycle. The generic form is closer to the actual code that will be produced in the end product than the instance form is.
We worked with the generic form in the previous column, and will continue to explore that form here. This time, we'll explore the role of conditional logic in a generic sequence diagram, thus expanding your knowledge of UML notation.
Conditional logic in sequence diagramming
Generic sequence diagrams make use of conditional logic, which can be useful for describing the alternative flow of events over the course of an interaction. You will employ different levels of granularity as you diagram, depending on where you are in the software development life cycle. In analysis, you might be content to leave the details out of your conditional expressions, whereas in design you might go so far as to include snippets of the code to be used in the end product.
Regardless of what phase of the development cycle you're in, the natural correspondence between sequence diagrams and an object-oriented language like the Java language becomes clear when it comes to diagramming conditional expressions. For example, consider a banking application that allows tellers to accept deposits. It has been specified, among other things, that the system must prevent tellers from crediting a negative amount to an account, which would result in a deduction from the account. The system must therefore have a mechanism to check that any amount that is keyed in is positive. Listing 1 shows the conditional expression that ensures the deposit is positive.
Listing 1. A method with a conditional expression
\** This is a method in a Teller class **\
public void receiveDeposit(Account account, BigDecimal deposit)
throws ImproperDepositException {
// Check to ensure the deposit is positive
(deposit.compareTo(new BigDecimal(0.0)) > 0) {
account.credit(deposit);
}
else {
throw new ImproperDepositException();
}
}
|
During the analysis stage you're not so concerned with the details, so your diagram needs only to signify that the deposit is positive. In a generic sequence diagram, a condition appears as a guard with the message name above the horizontal call arrow. These guard conditions are enclosed in square brackets to the left of the message name, as seen in Figure 3.
Figure 3. A condition added during analysis

The relationship between the method above and the sequence diagram becomes even clearer in Figure 4, where we see a more explicit diagram such as you might use in the design phase. Certainly the entire method is not illustrated: the else clause is missing. The semantics of the message arrows in the diagram do, however, dictate that the message may be sent only if the condition is valid.
Figure 4. A more explicit condition

The else clause would be modeled by adding another call arrow
between the Teller class and the
ImproperDepositException. On this call would be a
condition that was the converse of the if; in this case, that the
deposit must amount to less than or equal to zero. Perhaps you'd like
to try modeling this one for yourself?
As the example above shows, generic sequence diagrams -- and in fact
all UML diagrams -- closely map the Java language syntax. As a
result, most Java developers have an intuitive understanding of
these diagrams, and can learn to use them fairly quickly. To further
explore the correspondence between generic sequence diagrams and the
Java language, we'll diagram the for loop shown in Listing 2.
Listing 2. A for loop
for ( int i =0; i < 4; i++) {
squareRoom.examineCorner(i);
}
|
In sequence diagrams, iteration is symbolized by an asterisk (*)
preceding the message name on the horizontal arrow. If the number of
iterations is known and fixed -- a rare occurrence -- that number
appears in square brackets following the asterisk. Because most for
loops deal with complicated logic that does not allow the number of
iterations to be statically determined, you will not often employ this
form of bracket notation. The sequence diagram for the above for loop is
shown in Figure 5.
Figure 5. A for loop sequence diagram

The while loop is a perfect example to close with, as it
combines a loop with a condition. We'll diagram the while loop shown
in Listing 3.
Listing 3. A while loop
while ( value.notFound() ) {
value = database.search( key );
}
|
Our diagram for the while loop contains both a condition and an
asterisk, signaling iteration, but as you can see the number of
iterations is unavailable. A while loop will rarely include the
number of iterations -- unless it is a for loop in disguise. The
diagram for the while loop is shown in Figure 6.
Figure 6. A
while loop sequence diagram
Must and may behavior is a fundamental concept of UML and of software development in general. Use cases capture must behavior; scenarios capture may behavior. Class diagrams capture must behavior; instance diagrams capture may behavior. I have focused on this concept because I've found that many people fail to grasp the ultimate flexibility of sequence diagrams, and become polarized in their perception and use of the form.
When reading these articles, you should concentrate on developing an intuitive understanding of the semantics of the model. As you view more sequence diagrams and begin to create your own, you will find that many sequence diagrams rely on the existence of conditional logic and diagram context to signal whether the diagram presents a must or may view of the system. Learning to recognize and employ this distinction early on will aid you in the future, as we move into increasingly complex diagramming techniques.
In addition to exploring the significance of must and may behavior
in sequence diagramming, I've shown you how to denote conditions and
iteration in a diagram. Now that you've seen how for and while loops
are diagrammed, I invite you to practice your modeling notation on
other Java constructs, such as the do-while loop. As you practice
diagramming these simple constructs on your own, your understanding
of sequence diagramming will naturally improve.
- Another great resource is UML
in a Nutshell by Sinan Si Alhir (O'Reilly & Associates, 1998).
- The definitive source of the UML Standard is the OMG's Unified Modeling Language Specification (version 1.4 as of this writing).
- Read all of Granville Miller's Java Modeling articles.

Granville has 13 years of experience in the object-oriented community. He is coauthor of the Advanced Use Case Modeling series and has presented tutorials at various object-oriented technology conferences worldwide. His hands-on approach to object-oriented development has been the result of his work with companies that range from startups in the very early stages to some of the most established software giants. Granville is currently teaching seminars, tutorials, and classes in agile processes, methodology, and Java technology, as well as mentoring and helping to deliver aggressive projects. Contact Granville at rmiller@togethersoft.com.




