- Creating and Deleting Participants
- Loops, Conditionals, and the Like
- Synchronous and Asynchronous Calls
- When to Use Sequence Diagrams
A common issue with sequence diagrams is how to show looping and conditional behavior. The first thing to point out is that this isn’t what sequence diagrams are good at. If you want to show control structures like this, you are better off with an activity diagram or indeed with code itself. Treat sequence diagrams as a visualization of how objects interact rather than as a way of modeling control logic.
That said, here’s the notation to use. Both loops and conditionals use interaction frames, which are ways of marking off a piece of a sequence diagram. Figure 4.4 shows a simple algorithm based on the following pseudocode:
Figure 4.4. Interaction frames
procedure dispatch foreach (lineitem) if (product.value > $10K) careful.dispatch else regular.dispatch end if end for if (needsConfirmation) messenger.confirm end procedure
In general, frames consist of some region of a sequence diagram that is divided into one or more fragments. Each frame has an operator and each fragment may have a guard. (Table 4.1 lists common operators for interaction frames.) To show a loop, you use the loop operand with a single fragment and put the basis of the iteration in the guard. For conditional logic, you can use an alt operator and put a condition on each fragment. Only the fragment whose guard is true will execute. If you have only one region, there is an opt operator.
Interaction frames are new in UML 2. As a result, you may see diagrams prepared before UML 2 and that use a different approach; also, some people don’t like the frames and prefer some of the older conventions. Figure 4.5 shows some of these unofficial tweaks.
Figure 4.5. Older conventions for control logic
UML 1 used iteration markers and guards. An iteration marker is a * added to the message name. You can add some text in square brackets to indicate the basis of the iteration. Guards are a conditional expression placed in square brackets and indicate that the message is sent only if the guard is true. While these notations have been dropped from sequence diagrams in UML 2, they are still legal on communication diagrams.
Table 4.1. Common Operators for Interaction Frames
Operator |
Meaning |
---|---|
alt |
Alternative multiple fragments; only the one whose condition is true will execute (Figure 4.4). |
opt |
Optional; the fragment executes only if the supplied condition is true. Equivalent to an alt with only one trace (Figure 4.4). |
par |
Parallel; each fragment is run in parallel. |
loop |
Loop; the fragment may execute multiple times, and the guard indicates the basis of iteration (Figure 4.4). |
region |
Critical region; the fragment can have only one thread executing it at once. |
neg |
Negative; the fragment shows an invalid interaction. |
ref |
Reference; refers to an interaction defined on another diagram. The frame is drawn to cover the lifelines involved in the interaction. You can define parameters and a return value. |
sd |
Sequence diagram; used to surround an entire sequence diagram, if you wish. |
Although iteration markers and guards can help, they do have weaknesses. The guards can’t indicate that a set of guards are mutually exclusive, such as the two on Figure 4.5. Both notations work only with a single message send and don’t work well when several messages coming out of a single activation are within the same loop or conditional block.
To get around this last problem, an unofficial convention that’s become popular is to use a pseudomessage, with the loop condition or the guard on a variation of the self-call notation. In Figure 4.5, I’ve shown this without a message arrow; some people include a message arrow, but leaving it out helps reinforce that this isn’t a real call. Some also like to gray shade the pseudomessage’s activation bar. If you have alterative behavior, you can show that with an alternative marker between the activations.
Although I find activations very helpful, they don’t add much in the case of the dispatch method, whereby you send a message and nothing else happens within the receiver’s activation. A common convention that I’ve shown on Figure 4.5 is to drop the activation for those simple calls.
The UML standard has no graphic device to show passing data; instead, it’s shown by parameters in the message name and return arrows. Data tadpoles have been around in many methods to indicate the movement of data, and many people still like to use them with the UML.
All in all, although various schemes can add notation for conditional logic to sequence diagrams, I don’t find that they work any better than code or at least pseudocode. In particular, I find the interaction frames very heavy, obscuring the main point of the diagram, so I prefer pseudomessages.