Chapter 10. Interaction Diagrams

A fundamental goal of UML 2.0 is to allow users to capture more than just structural relationships. UML 2.0 is intended to capture processes and flows of events. Interaction diagrams draw from nearly every other facet of the language to put together a set of diagrams that capture communications between objects. UML 2.0 has greatly expanded UML 1.x’s ability to describe complex flow of control; one of the largest sections of the UML 2.0 specification is the interaction diagrams section. Because of the expanded functionality, quite a bit of new terminology has been introduced. We’ll cover all the terms in this chapter and try to give you a feel for what terms are really critical and which are there to formalize the specification.

What Are Interactions?

Interaction diagrams are defined by UML to emphasize the communication between objects, not the data manipulation associated with that communication. Interaction diagrams focus on specific messages between objects and how these messages come together to realize functionality. While composite structures show what objects fit together to fulfill a particular requirement, interaction diagrams show exactly how those objects will realize it.

Interaction diagrams are typically owned by elements in the system. For example, you may have an interaction diagram associated with a subsystem that shows how the subsystem realizes a service it offers on its public interface. The most common way of associating an interaction diagram with an element is to reference the interaction diagram in a note attached to the element.

You can show the details of an interaction using several different notations; however sequence diagrams are by far the most common. Other notations include interaction overviews, communication diagrams, timing diagrams, and interaction tables. Because sequence diagrams are used most frequently, each concept is introduced using that notation. The other notations are described in detail later in the chapter. The basic symbol for an interaction diagram is a rectangle with the keyword sd and the name of the interaction in a pentagon in the upper-left corner. Figure 10-1 shows an example sequence diagram. The various parts of this diagram are explained throughout the chapter.

A sample sequence diagram
Figure 10-1. A sample sequence diagram

Interaction Participants

You show participants in an interaction using a rectangle called a lifeline. The term lifeline illustrates UML’s bias toward representing interaction diagrams using the sequence diagram notation. When shown in sequence diagrams, participants have a dashed line dropping down from a rectangle that shows how long the object is actually in existence. When used in other interaction diagram notations, such as communication diagrams, a lifeline is simply a rectangle. You show the name of the participant in the rectangle using the following notation:

            
    object_name [ selector ] : class_name ref decomposition

where:

object_name

Specifies the name of the instance involved in the interaction.

selector

Is an optional part of the name that can identify which particular instance in a multivalued element is to be used (for example, which EventHandler in an array of EventHandlers).

class_name

Is the name of the type of this participant.

decomposition

Is an optional part of the name that can point to another interaction diagram that shows details of how this participant processes the messages it receives (see "Decomposition“).

UML defines a reserved participant name, self, that indicates the participant is the classifier that owns this interaction diagram.

Figure 10-2 shows a trivial interaction diagram with two participants and a message between them.

A trivial sequence diagram with two participants
Figure 10-2. A trivial sequence diagram with two participants

You can show the destruction of a participant during an interaction using a stop symbol. Typically this is preceded by a «destroy» message to the object, though that isn’t strictly necessary. Place an X at the bottom of the lifeline where the object ceases to exist. Figure 10-3 shows destroying a helper class after it has finished its work.

The destruction of a participant
Figure 10-3. The destruction of a participant

To help make your sequence diagram accurately capture the behavior you are trying to model, you can introduce local variables . Local variables can hold return values, loop information, or just data you need for later processing. You show the values of local attributes relevant to the interaction using the same attribute syntax used inside of classifiers (see Chapter 2). Place their name and values in the upper left of the diagram, or in a note attached to the diagram. Figure 10-4 shows a more detailed version of the HashMap interaction using local variables.

A more complete HashMap interaction using local variables
Figure 10-4. A more complete HashMap interaction using local variables

In addition to local variables, sequence diagrams can access data in the participants. See "Messages" for examples.

Messages

The focus of interaction diagrams is on the communication between lifelines. This communication can take many different forms: method calls, sending a signal, creating an instance, destroying an object, etc., all of which are collectively called messages . A message specifies the kind of communication, its sender, and its receiver. For example, a PoliceOfficer class instantiating a SpeedingTicket class is represented as a message from an instance of PoliceOfficer to the newly created instance of SpeedingTicket.

The most common use of messages is to represent method calls between two objects. When messages are used to indicate a method call, you can show the parameters passed to the method in the message syntax. The parameters should be one of the following:

  • Attributes of the sending object

  • Constants

  • Symbolic values (expressions showing what the legal values can be)

  • Explicit parameters of the enclosing interaction

  • Attributes of the class owning the enclosing interaction

The syntax for a message is:

            
    attribute = signal_or_operation_name (arguments) : return_value

where:

attribute

Is an optional part of the syntax that provides a shorthand way of showing that the return value from this message is stored in the specified attribute. The attribute must be an attribute of the lifeline sending the message, a global attribute of the interaction, or an attribute of the class owning the interaction.

signal_or_operation_name

Specifies the name of the operation to invoke or the signal being emitted.

arguments

A comma-separated list of arguments to pass to the operation or signal. The arguments may be values or parameter names. If only argument values are used, arguments are matched against the operation or signal signature, in order. If you want to skip an argument, place a dash (-) where the argument would be. Skipped arguments have unknown values. You can explicitly identify a parameter name by following the text name with a colon (:) and then the value. If you use parameter names, you can omit arguments not relevant to the interaction. As with a dash, skipped arguments have unknown values.

You can prefix an argument with the keyword out or inout to indicate the argument is used to return a value. If the argument is used as an out argument, a value after the colon in the argument specification is interpreted to be the return value.

return_value

Explicitly states what the return value from this message will be.

Message notation varies based on the specific notation you use to show the details of the interaction. Because the most common representation of interactions is with sequence diagrams, you use the notation that’s common with such diagrams. See the specifics about other notations in “Alternate Interaction Notations.”

When using sequence diagram notation, you show a message as a solid line pointing from the sender’s lifeline to the receiver’s lifeline. If the message is an asynchronous message (meaning the caller doesn’t block waiting for the receiver to process the message), you place an open arrowhead on the receiver’s end of the line. Figure 10-5 shows an example of an asynchronous message.

An asynchronous message between objects
Figure 10-5. An asynchronous message between objects

When returning a book to the library, you typically don’t wait around for the librarian to return the book to the shelves. Instead, you drop the book off at the Circulation Desk and continue on your way. The open arrowhead indicates that the caller (AverageJoe) doesn’t wait for any response from the CirculationDesk.

Because asynchronous messages don’t require the sender to wait for a message to be delivered, depending on the transport mechanism, asynchronous messages can arrive out of order. For example, two network packets can take different routes to the same destination, with the second arriving before the first. You can show out-of-order reception by having the first message point to a spot below the reception point of the second message, as shown in Figure 10-6.

Asynchronous messages received out of order
Figure 10-6. Asynchronous messages received out of order

In this example HostMachine sends two ping packets to DestinationMachine. Because of network differences in the routes taken, the response to the second ping arrives before the response to the first ping.

If a message represents synchronous communication (typically a method call), you place a filled arrow head on the receiver’s end. You can show return values from a method using a dashed line with an open arrowhead pointing back to the caller. Figure 10-7 shows a method call to order an item and a confirmation number sent back as a return value.

If a message represents object creation, you show a dashed line, with an open arrow pointing to the newly created object’s lifeline. By convention, the message is typically labeled with some variation of create. If there are no arguments to the message, you can simply label the message with the keyword «create», as in Figure 10-3. If there are arguments, you show them as parameters to a create() message. If there is a particular reason to show the creation message using a different label (such as a factory method), you should use that. Figure 10-8 shows an example that creates an instance of the class UserAccount.

A method call and the resulting return value
Figure 10-7. A method call and the resulting return value
Showing object instantiation
Figure 10-8. Showing object instantiation

Although this technique isn’t mentioned in the specification, some modelers prefer to lower the rectangle representing the object to the end of the message line to clearly indicate the object didn’t exist before this creation event. The advantage of this notation is that it clearly shows when the object comes into existence; the disadvantage is that you can’t skim the top row and view the participants. Figure 10-9 shows the same diagram but lowers the newly created object.

UML defines two special types of messages: lost messages and found messages . Lost messages are messages that are sent but never reach their destination. Found messages are messages that are received by an object but the sender is unknown. For example, if you want to model an exception-handling mechanism, the sending of the exception is really irrelevant to the mechanism itself, so you can model that as a found message. Understand that unknown senders and receivers are relative concepts. The sender or receiver of a message may be unknown as far as a

Object instantiation with the object lined up with the creation message
Figure 10-9. Object instantiation with the object lined up with the creation message

particular interaction is concerned, meaning it’s really outside the scope of what you are trying to show, not that the message necessarily vanishes from existence (though that’s permissible too).

You show a found message by starting the message from a black circle rather than the sender’s lifeline. Figure 10-10 shows an example of a found message. The CircuitBreaker doesn’t care where the power surge came from; it must terminate the power in all conditions.

An example of a found message
Figure 10-10. An example of a found message

Similarly, you show a lost message by terminating the message arrow at a black circle rather than a receiver’s lifeline. Figure 10-11 shows a Workstation sending out a ping message that for some reason, (network failure) isn’t received.

An example message being lost
Figure 10-11. An example message being lost

Execution Occurrences

You can show an object is involved in executing some type of action (typically a method call) for a measurable amount of time using an execution occurrence. Execution occurrences are shown as gray or white rectangles on a lifeline. In practice, it is common to hear execution occurrences called “focus of control,” because they indicate that an object is busy (has the focus of the system) for some period of time. Figure 10-12 shows several execution occurrences in response to messages.

Several example execution occurrences
Figure 10-12. Several example execution occurrences

While not officially part of the specification, it was a common practice in UML 1.x to show messages starting from an execution occurrence on a lifeline to indicate that an object will send messages to other objects as part of processing a received message. With UML 2.0, it may be more appropriate to show a set of messages as an interaction fragment. Using interaction fragments, an appropriate interaction operator, and a reasonable name, you have much greater flexibility in expressing exactly how a piece of the system executes and how it fits into the bigger picture. See "Combined Fragments" for more information on interaction fragments and the various ways you can organize messages to increase your diagram’s readability.

State Invariants

UML allows you to place labels along a lifeline to convey conditions that must be true for the remainder of the interaction to be valid. These conditions are called state invariants . State invariants are typically boolean expressions, though they may be full UML states (see Chapter 8). For example, you may have a series of messages that initialize a participant. After the messages have completed, the participant must be in a well-known state for the remainder of the interaction to complete successfully. You can enforce that by placing a state invariant on your diagram after the initialization messages.

You show a boolean state invariant by simply placing the conditional inside curly braces ({}) on the lifeline of the object you want to check. The invariant will be evaluated after any messages that come above it on the diagram. Figure 10-13 shows a basic boolean invariant checking that an Account has been authenticated successfully.

A state invariant ensuring that the account is in the proper state before continuing
Figure 10-13. A state invariant ensuring that the account is in the proper state before continuing

You show an invariant as a UML state by simply drawing the state symbol (rectangle with rounded sides) over the appropriate part of the lifeline of the object you want to check. The actual information that is validated by the state can be expressed using the normal UML state diagram notation. Figure 10-14 shows the same Account authentication using a UML state.

UML allows you to place the state invariant information inside a note and link it back to the lifeline, though this doesn’t tend to be as obvious to the reader as seeing a constraint directly on the lifeline in the proper sequence. Figure 10-15 shows a state invariant using a note.

A state invariant using a real UML state
Figure 10-14. A state invariant using a real UML state
A state invariant using a note; authenticated must be true when setPhoneNumber is called
Figure 10-15. A state invariant using a note; authenticated must be true when setPhoneNumber is called

Event Occurrences

Event occurrences are the smallest building blocks of interaction diagrams; they represent moments in time when something happens. Sending and receiving a message are the most common types of event occurrences, though technically they can be any action associated with an object. For example, if object1 sends a message to object2, there are two event occurrences, a message send and a message receive. UML carefully defines interaction fragments as a set of event occurrences where ordering is significant because they represent events over time.

Each type of interaction diagram notation (sequence, communication, etc.) has a way of expressing the time-sensitive nature of the event occurrences. In a sequence diagram the event occurrences are ordered along the lifelines and are read from top to bottom. Figure 10-16 shows a sequence diagram with three of the event occurrences labeled (as mentioned earlier, any action associated with an object is an event occurrence, but to keep the diagram from getting out of control only three are labeled in the figure).

A sequence diagram with three event occurrences labeled
Figure 10-16. A sequence diagram with three event occurrences labeled

Traces

UML defines a trace as a sequence of event occurrences. The term trace is used when discussing sets of event occurrences and how they may be combined. Interaction diagrams allow you to combine fragments in such a way that the event occurrences are interleaved. This combined set of event occurrences is considered a new trace.

Throughout this chapter we will refer to a sequence of event occurrences as event occurrences rather than as a trace to try and reduce the number of keywords.

Combined Fragments

Often there are times when a particular sequence of event occurrences has special constraints or properties. For example, you may have a critical region within your interaction where a set of method calls must execute atomically, or a loop that iterates over a collection. UML calls these smaller pieces interaction fragments.

Interaction fragments by themselves aren’t terribly interesting, however UML allows you to place them in a container called a combined fragment (it’s called a combined fragment even if you have only one interaction fragment in there). Once they are placed in such a container, UML allows you to specify additional detail for each fragment, or how several fragments relate to each other.

Each combined fragment is made up of an interaction operator and one or more interaction fragments, which are the interaction operands. An interaction operator specifies how the interaction operands should be interpreted. The various interaction operators are described in detail later in this chapter.

As you do with full interactions, you show a combined fragment as a rectangle, with the interaction operator in a pentagon in the upper left and the interaction operands inside the rectangle. Figure 10-17 shows a combined fragment representing a critical section of code. The code must be executed atomically because of the interaction operand critical. This and other interaction operators are described in "Interaction Operators.”

An example combined fragment
Figure 10-17. An example combined fragment

Depending on the interaction operator you choose for a combined fragment, you may need to specify multiple operands. You separate operands using a horizontal dashed line across the rectangle. Messages aren’t permitted to cross between interaction fragments. The order of the operands is significant for some of the operators, so always read a combined fragment from top to bottom. See Figure 10-18 for an example of multiple operands.

Guard Conditions

An interaction fragment may have a guard condition that states when the fragment is valid (can be executed); as in an “if-then” condition. The syntax for a guard condition is simply:

    [ boolean_expression ]

You show a guard condition directly above the first event occurrence in the relevant interaction fragment and on top of the associated lifeline. A guard condition can refer to any local data available to that lifeline, or to any global data available to the overall interaction; it can’t refer to the local data of some other lifeline. Figure 10-18 shows an example of an alternative interaction operator that models an if-else condition.

See the description for each interaction operator to see when guard conditions are necessary and how they are used. If you don’t place a guard condition before an interaction fragment, it is interpreted as a guard condition that always evaluates to true.

Interaction Operators

Each interaction operator defined in the UML 2.0 specification is explained in detail in the following sections. Each operator has an associated number of operands and a keyword that is placed in the pentagon of a combined fragment.

Alternatives

Alternates are a choice of the behavior that executes based on guard conditions placed before each operand. The interaction operator is alt. You may include an else guard condition that executes the associated operand when the other conditions are false. Figure 10-18 shows this.

Example alternative operator
Figure 10-18. Example alternative operator

Option

Options are interaction fragments that executes only if the guard condition is true. The interaction operator is opt. Conceptually, options are similar to an alt operator with only one operand. Figure 10-19 shows an option operator.

Break

A break indicates that the associated interaction fragment operand should execute and then terminate the enclosing interaction. The interaction operator is break. A break is similar to the following code block:

    if (guardCondition) { ... ; return; }
Example option operator
Figure 10-19. Example option operator

Figure 10-20 shows a break operator.

Example break operator
Figure 10-20. Example break operator

Parallel

Parallel indicates that the associated interaction fragments may be merged and executed in parallel. The interaction operator is par. UML specifies that the actual interleaving of the event occurrences of the operands must be done in such a way that the ordering in the original operand is maintained. For example, if the first operand consists of:

    Step1
    Step2
    Step3

and the second consists of:

    StepA
    StepB
    StepC

they can be merged into:

    Step1
    StepA
    StepB
    Step2
    StepC
    Step3

but not into:

    Step1
    StepB
    Step2
    StepA
    Step3
    StepC

because stepA and stepB would be executed out of order. Figure 10-21 shows an example of the parallel operator to model a desktop login sequence.

Example parallel operator
Figure 10-21. Example parallel operator

If you need to convey that a particular event occurrence must come before another event occurrence, UML has an explicit notation called a general ordering . You can show a general ordering anywhere in an interaction diagram, but it must connect two event occurrences. You simply draw a dotted line between the two event occurrences, with a solid arrow in the middle of the line pointing toward the occurrence that must happen second. For example, if you don’t want the login splash screen in Figure 10-21 to be hidden until all the applications are started, you can indicate that the startUserLoginApps() call must occur before the hideLoginSplashScreen() call. Figure 10-22 shows how to use a general ordering to indicate that the application startup must complete first.

Example general ordering
Figure 10-22. Example general ordering

Weak sequencing

Weak sequencing indicates that the event occurrences in each operand can be interleaved according to the following rules:

  1. The ordering of the event occurrences within each operand is maintained. For example, if the first operand has <step1, step2, step3> and the second operand is <stepA, stepB, stepC>, they may be interleaved to <step1, stepA, step2, stepB, step3, stepC> because the order is maintained, but not to <step1, step3, stepA, step2, stepB, stepC> because the ordering of the event occurrences in the first operand is changed.

  2. If event occurrences in different operands occur on different lifelines, they can be interleaved in any order.

  3. If event occurrences in different operands occur on the same lifeline, they can be interleaved only in such a way that the event occurrences of the first operand execute before the occurrences of the second operand.

The interaction operator is seq. For Figure 10-22, a weak sequencing wouldn’t change the way the calls are interleaved because the first operand has calls only to DesktopService and the second operand has calls only to the ApplicationService. However, if the sequence is changed so that the second operand includes a call to the DesktopService, it isn’t allowed to execute until all the calls to DesktopService in the first operand are complete (Rule #3). Figure 10-23 shows this new sequence diagram.

Example of a weak sequencing operator
Figure 10-23. Example of a weak sequencing operator

Strict sequencing

Strict sequencing indicates that the ordering of the event occurrences is significant across lifelines, not just within the same lifeline (as with weak sequencing). The operands of a strict sequence must be executed in order, from top to bottom. The interaction operator is strict.

Negative

Negative indicates a set of event occurrences that are considered invalid, meaning the interaction can never execute this particular path. The interaction operator is neg. This particular operator is rarely used but can convey that the particular sequence isn’t permitted. Figure 10-24 shows an example of an invalid call to a Graphics2D object. In this diagram, a UML note indicates to the reader why the particular sequence is invalid.

Critical region

A critical region indicates that the given event occurrences must be treated as an atomic block. The interaction operator is critical. Critical regions are typically used inside other interaction fragments (such as a parallel fragment) to ensure that a group of event occurrences can’t be separated.

Figure 10-25 shows an example rendering engine loop that checks to see if map data is available for drawing. Because loading map data may be an expensive operation, we’ll allow the loading to be executed in parallel with the rendering. However, compressed map data can’t be rendered, so the loading and decompression must occur as an atomic operation.

Example of a negative operator
Figure 10-24. Example of a negative operator
Example of a critical region operator
Figure 10-25. Example of a critical region operator

Because Figure 10-25 needs to represent a continuously running process (the rendering loop), it’s better to model the looping conditions with the loop operator shown later in this chapter (see "Loop“).

Ignore/consider

Ignore specifies a set of messages that aren’t shown on the interaction fragment and can be safely ignored. This typically implies that the ignored messages are irrelevant for the purpose of the diagram; however, they may still occur during actual execution. The interaction operator is ignore, and the syntax is:

    ignore { messagename, messagename, ... }

Figure 10-26 shows an example of the ignore operator that models a simple mail transmission protocol. In this sequence, ping and status messages are explicitly ignored. This means they can occur anywhere during this sequence and should be handled by the system, but are irrelevant to the flow of execution we’re trying to model.

Example of an ignore operator
Figure 10-26. Example of an ignore operator

Consider specifies a set of messages that are explicitly relevant to the diagram, so you can safely ignore any other message. The interaction operator is consider, and the syntax is:

    consider { messagename, messagename, ... }

Figure 10-27 shows the same mail transmission sequence as that shown in Figure 10-26 but explicitly considers authenticateUser, sendEnvelope, sendBody, disconnect, shutdown, and reset. Because shutdown and reset aren’t shown on the sequence diagram, it’s invalid for either message to occur during execution.

Assertion

An assertion indicates that the contained event occurrences are the only valid execution path. The interaction operator is assert. Assertions are typically combined with some kind of state invariant to enforce a state of a system.

Figure 10-28 shows a sequence diagram in which the user requests that maps be redrawn. The RenderingEngine instructs the DrawingSurface to remove all the existing textures, and the assertion guarantees there are no textures left.

Loop

A loop indicates that the contained event occurrences are to be executed some number of times. The interaction operator is loop. The notation for a loop includes a minimum and maximum number of times a loop should execute. You

Example of a consider operator
Figure 10-27. Example of a consider operator
Example of an assertion operator
Figure 10-28. Example of an assertion operator

may also use a guard condition that is evaluated each time through the loop to terminate execution. The syntax for the operator is:

    loop (min, max)

where both min and max are optional. If max is excluded, max equals min. max may be an asterisk (*) to indicate an infinite loop (or at least while the guard condition evaluates to true). If both min and max are excluded, min equals 0, and max equals infinity; in this case you likely want to have a guard condition to prevent the loop from executing indefinitely.

Figure 10-29 shows the rendering loop modeled in Figure 10-25. In this sequence diagram, the looping is explicitly shown with a guard condition that will terminate the loop when the user has set the quit flag to be true. There is also an inner loop that instructs the MapLoader to execute while there are maps to load.

Example of a loop operator
Figure 10-29. Example of a loop operator

Interaction Occurrences

An interaction occurrence is shorthand for copying one interaction into another, larger interaction. For example, you can create an interaction that simply shows user authentication and then reference it (create an interaction occurrence) in larger, more complete interaction diagrams.

The syntax for an interaction occurrence is a combined fragment rectangle with the interaction operator ref. Place the name of the referenced interaction in the rectangle. UML allows parameters to be passed to referenced interactions using the following syntax:

            
    attribute_name = collaboration_occurrence.interaction_name ( arguments ) : return_value

where:

attribute_name

Is an optional part of the syntax that specifies what attribute the return value should be applied to. The attribute must be an attribute of a lifeline in the larger interaction.

collaboration_occurrence

Is an optional scoping of the referenced interaction if it is part of a larger collaboration.

interaction_name

Is the name of the interaction to copy.

arguments

Is a comma-separated list of arguments to pass to the referenced interaction. The arguments may be values or parameter names. If only argument values are used, arguments are matched against the interaction parameters, in order. If you want to skip an argument, you place a dash (-) where the argument would be. Skipped arguments have unknown values. You may explicitly identify a parameter name by following its text name with a colon (:) and then the value. If you use parameter names, you may omit arguments not relevant to the interaction. As with a dash, skipped arguments have unknown values.

You may prefix an argument with the keyword out or inout to indicate that the argument is used to return a value. If the argument is used as an out argument, a value after the colon in the argument specification is interpreted to be the return value.

return_value

Is an optional part of the reference that, if present, indicates the value returned by the copied interaction.

Figure 10-30 shows a simple mail transmission sequence diagram that uses an interaction occurrence to refer to another sequence diagram that illustrates user authentication. In this example, the return value from the interaction occurrence is ignored, so it isn’t assigned to any variable.

Example of an interaction occurrence
Figure 10-30. Example of an interaction occurrence

Decomposition

A participant in an interaction diagram may be a complex element in and of itself. UML allows you to link interaction diagrams by creating a part decomposition reference from a participant to a separate diagram. For example, you may have a Purchase Item interaction diagram that has a participant execute a credit card authorization. The actual details of the authorization process are probably not of interest to the readers of your Purchase Item diagram; however, they are vitally important to the developers responsible for the authorization subsystem. To help reduce clutter on your diagrams, you can create a separate diagram showing how the authorization subsystem validates credit cards and place a decomposition reference to that on the Purchase Item diagram.

To create a part decomposition reference, simply place ref interaction_diagram_name after the instance name in the head of your lifeline. Figure 10-31 shows how the Purchase Item and authorization diagrams can be modeled.

Example of a decomposition diagram
Figure 10-31. Example of a decomposition diagram

Messages that come into or out of the decomposed lifeline are treated as gates that must be matched by corresponding gates on the decomposition. A gate represents a point where a message crosses the boundary between the immediate interaction fragment and the outside environment. A gate has no symbol of its own; you simply show a message pointing to the edge of the frame of an interaction fragment. The entire purpose of a gate is to show an object that sent a message connecting to the object that received the message.

By default, a gate’s name is based on the direction (in or out) and the message in question. For example, a gate showing a message named verifyPayment leaving an interaction fragment is named out_verifyPayment. However, you may explicitly name gates if that adds readability to your diagram.

If the messages shown in the decomposition are part of a combined fragment in the larger interaction diagram, the decomposition must inherit the same interaction operand. UML defines this as extra-global . For example, if the larger interaction is part of an assert interaction operand, and the state invariant is declared on the lifeline you want to decompose, that state invariant (and its assertion) must apply to your decomposition. You can show extra-global combined fragments by drawing the combined fragment on your decomposition, but making the combined fragment rectangle larger than your decomposition rectangle. Figure 10-32 shows an assertion decomposition of the rendering engine example used earlier in this chapter.

Example of a decomposition with extra-global fragments
Figure 10-32. Example of a decomposition with extra-global fragments

The UML specification recommends that you name your decomposition diagrams using an abbreviation for the object being decomposed, followed by an underscore (_), followed by the name of the interaction. For example, if you are modeling a credit card authorization system and want to show how a card is validated, you can name your decomposition CCAS_Validation.

You can also show decompositions inline by showing parts of the decomposed element attached as smaller rectangles to the bottom of the head of the lifeline. Each part gets its own lifeline. This can be useful to show inner classes receiving or sending messages. For example, it is common practice in Java to declare an inner anonymous class to handle GUI events. If you felt this was relevant to your interaction you can show this level of detail on the main interaction diagram. However, inline notation is relatively uncommon because decompositions are typically used to show a complex, subinteraction that would clutter the top-level diagram.

Figure 10-33 shows an example inline part decomposition where MainWindow has two inner classes: an anonymous WindowListener and an instance of an EventHandler named mEventHldr.

Example of an inline decomposition
Figure 10-33. Example of an inline decomposition

Continuations

Typically used with interaction references, continuations allow you to define different branches of an alternative interaction outside of the alternative itself. Continuations are conceptually similar to named blocks of functionality.

The notation for continuations can be particularly confusing. You show a continuation using the symbol for states, a rectangle with rounded sides; however, the position of the rectangle changes the meaning of the diagram. You place a continuation at the beginning of an interaction to define the behavior for that continuation. You use a continuation by showing the rectangle at the end of an interaction. Finally, continuations with the same name must cover the same lifelines (and only those lifelines).

Figure 10-34 shows the first of three sequence diagrams demonstrating a continuation; this one displays the details of a Login sequence. After the password is retrieved from the database, an alternative interaction is entered. If the passwords match, various flags are set on the UserCredentials. After setting the flags, there is a continuation named Login success, in which users of this sequence diagram can plug in their own functionality. If the passwords don’t match, the else part of the alternative interaction executes, which leads to the Login failed continuation. Notice the continuation symbols are at the end of each interaction operand, indicating this diagram uses an externally defined continuation.

Using a continuation in a sequence diagram
Figure 10-34. Using a continuation in a sequence diagram

Figure 10-35 shows the second diagram, a sequence diagram that makes use of the Login sequence and defines continuations for Login success and Login failed. If the correct password was entered, the Login success continuation is executed; otherwise, the Login failed continuation is run. Notice in this diagram that the continuation symbols are at the top of the interaction, indicating that this diagram defines the behavior to execute.

Defining continuations in a sequence diagram
Figure 10-35. Defining continuations in a sequence diagram

Taken together, these two diagrams are equivalent to Figure 10-36.

Sequence Timing

UML provides a notation to capture a specific time associated with an event occurrence. You simply place a small horizontal line next to an event occurrence to capture the time of the occurrence, or place a timing constraint on it. Typically, you use a variable to capture a specific instance in time and then represent constraints as offsets from that time. Constraints are expressed like state invariants and placed next to the event occurrence.

For example, if you want to express that a credit card authorization system must return approval or denial within three seconds of placing the request, you can place time constraints on the event occurrence, as shown in Figure 10-37.

Alternate Interaction Notations

UML provides several notations for capturing interactions. The first part of this chapter used the sequence diagram notation. The remainder of this chapter describes the other notations available and when they may be more appropriate than sequence notation.

The final sequence, with all continuations expanded
Figure 10-36. The final sequence, with all continuations expanded

Communication Diagrams

Communication diagrams allow you to focus on the elements involved in interactions rather than the detailed sequencing and flow control allowed in sequence diagrams. Most UML tools can automatically convert from a sequence diagram to a communication diagram; however, because communication diagrams aren’t as expressive,.some information may be lost.

When you’re modeling with communication diagrams, objects are represented by a rectangle, and connections between objects are shown as a solid line. Each message has a sequence number and a small arrow indicating the direction of the message along a given connection. Communication diagrams can’t show message overtaking (see Figure 10-6 earlier in the chapter) or interaction fragments.

Figure 10-38 shows a simple sequence diagram and the equivalent communication diagram.

The syntax for a message name is:

               
    sequence_number: name [ recurrence_or_guard ]
A sequence diagram with hard timing requirements
Figure 10-37. A sequence diagram with hard timing requirements
Example of a sequence diagram and its equivalent communication diagram
Figure 10-38. Example of a sequence diagram and its equivalent communication diagram

where:

sequence_number

Is the index of the message with 1 being the index of the first message in the diagram. You show nested message calls by appending the original message number with a decimal and then starting a new sequence. For example, if the listen() call in Figure 10-38 makes a nested call to startTimer(), number startTimer() as 3.1.

You can show concurrent messages using letters in the sequencing. For example, if the ListentingPort instance can support multiple parallel listening calls, the MainWindow instance can call the listen() call twice, labeling the first call as 3a and the second as 3b. Both calls can execute concurrently.

name

Is the name of the message being sent (or method call).

recurrence_or_guard

Is an optional part of the syntax that allows you to specify a boolean condition that must be true for the message to occur, or a range of integer values for looping. Guard conditions are represented as normal boolean expressions; for example, [password.Valid == true]. UML doesn’t provide a syntax for specifying looping constraints but does say they must begin with an asterisk (*). For example, you can represent a loop that executes from 0 to 10 as *[i = 0 .. 10].

Interaction Overview Diagrams

Interaction overview diagrams represent interactions using a simplification of the activity diagram notation (see Chapter 9). Interaction overview diagrams can help you visualize the overall flow of control through a diagram; however, they don’t show detailed message information.

You can embed interactions or interaction occurrences inside an interaction overview diagram if it is helpful to see message details for a subset of the overall interaction.

Several sequence diagram concepts are supported in interaction overview diagrams :

  • Show combined fragments using a decision node and merge node.

  • Show parallel interactions by using a fork node and join node.

  • Show loops as cycles in the activity diagram.

  • Show names of the lifelines involved in an interaction using the keyword lifelines after the name of the interaction overview diagram, followed by a comma-delimited list of each lifeline’s name (including any colon separators that may or may not be part of the name).

Figure 10-39 is an interaction overview diagram showing a subset of the interaction shown in Figure 10-36.

Timing Diagrams

Timing diagrams are a special representation of interactions that focus on the specific timings of messages sent between objects. You can use timing diagrams to show detailed time constraints on messages or to show when changes occur within lifelines with respect to time. Timing diagrams are most often used with real-time or embedded systems.

Unlike sequence diagrams, timing diagrams are read left to right rather than top to bottom. You show a lifeline name along the left edge of the diagram. The various states of the lifeline are then listed, followed by a graphical representation of the transitions between these states. Figure 10-40 shows an example of a timing diagram in which the MailServer object progresses through several states.

In Figure 10-40, the MailServer starts in the Idle state until the Login event occurs. The Login event causes the MailServer to transition to Authenticated. When the sendMail event occurs, the MailServer transitions to Transmitting and remains there until disconnected.

Example of an interaction overview diagram
Figure 10-39. Example of an interaction overview diagram
Simple timing diagram
Figure 10-40. Simple timing diagram

When reading the diagram left to right, you can use the length of the timeline to indicate how long the object remains in a particular state. To associate time measurements, you show tick marks along the bottom part of the frame, as shown in Figure 10-41.

Timing diagram with tick marks
Figure 10-41. Timing diagram with tick marks

Figure 10-41 shows that the Login event is received three time units after the start of the sequence. To show relative times , you can mark a specific instance in time using a variable name. Figure 10-41 marks the time the sendMail event is received as time t. You can use relative time marks in constraints to indicate that a message must be received within a specified amount of time. Figure 10-42 shows the Disconnect message must be received within 10 time units of the sendMail event.

You can show multiple objects involved in a timing diagram by stacking the lifelines. You show messages between objects using an arrow from one timeline to another. The start and end of the arrow correspond to when the message is sent and received. This notation shows the triggers that cause a transition; however it

Timing diagram with time constraints
Figure 10-42. Timing diagram with time constraints

very quickly becomes unreadable if a lot of messages are exchanged. Figure 10-43 shows the MailServer talking with a client, Desktop.

Timing diagram with multiple lifelines and messages
Figure 10-43. Timing diagram with multiple lifelines and messages

UML provides a variation on the timeline notation that simplifies diagrams by showing state names between two horizontal lines that cross when the state changes. This notation makes it much easier to show multiple objects along a single timeline, but it doesn’t show the messages that trigger transitions. Figure 10-44 shows the MailServer and Client lifelines progressing through state transitions.

Timing diagram using a simpler timeline notation
Figure 10-44. Timing diagram using a simpler timeline notation
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.203.68