10.8. Combined FragmentsOften 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." Figure 10-17. An example combined fragmentDepending 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. 10.8.1. Guard ConditionsAn 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. 10.8.2. Interaction OperatorsEach 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. 10.8.2.1. AlternativesAlternates 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. Figure 10-18. Example alternative operator10.8.2.2. OptionOptions 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. 10.8.2.3. BreakA 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; } Figure 10-19. Example option operatorFigure 10-20 shows a break operator. Figure 10-20. Example break operator10.8.2.4. ParallelParallel 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. Figure 10-21. Example parallel operatorIf 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. Figure 10-22. Example general ordering10.8.2.5. Weak sequencingWeak sequencing indicates that the event occurrences in each operand can be interleaved according to the following rules:
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. Figure 10-23. Example of a weak sequencing operator10.8.2.6. Strict sequencingStrict 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. 10.8.2.7. NegativeNegative 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. 10.8.2.8. Critical regionA 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. Figure 10-24. Example of a negative operatorFigure 10-25. Example of a critical region operatorBecause 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"). 10.8.2.9. Ignore/considerIgnore 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. Figure 10-26. Example of an ignore operatorConsider 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. 10.8.2.10. AssertionAn 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. 10.8.2.11. LoopA 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 Figure 10-27. Example of a consider operatorFigure 10-28. Example of an assertion operatormay 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. Figure 10-29. Example of a loop operator |