Summary
A loop is a contiguous path of associations that originates and terminates on the same class. A reflexive association is the simplest case of a loop.
Two modeling errors are common when it comes to modeling loops: redundant loops and imprecise loops.
Redundancy is bad. You should omit associations that close a loop without adding any new information. Each association must capture rules or facts about the application not previously modeled.
The correct level of constraint on each loop must be specified. When both ends of a loop come together, there is some level of constraint on what instances may link together. In the unconstrained case, any instance in one class may link to any instance on the other side of the association (on any association in the loop) without regard to any other existing links in the loop. In the constrained case, other links must be taken into account to determine which instances are eligible for linking on any given association in the loop.
The following constraints have been introduced in this chapter:
Loop {concatenation of all associations in the constrained loop}. For example, R1 {R1+R5+R6} indicates that R1 is part of a loop, R1+R5+R6, which is constrained.
Reflexive {an attached association}. For example, R1 {R2}, where R1 is a reflexive association and R2 is a nonreflexive association attached to R1, indicates that links on R1 must start and end on instances linked to the same instance across R2.
Reflexive {acyclic}. For example, R7 {acyclic}, where R7 is a reflexive association, says that an instance may not link to itself across R7.
Remember that, in Executable UML, notation has to be backed up by semantics. All notational elements, whether graphic, text or both, must be backed up by an unambiguous formalism. Constraints on associations can be specified either in the action language of the procedure models, or in a corresponding OCL expression. If you think of a constraint not expressed in Executable UML, write the corresponding OCL expression. Then you can invent your own constraint name (such as "acyclic") to put between the Rx {} brackets.
Constraints are important. If the class model does not reflect selection constraints, subsequent procedure models will often ignore or misrepresent the constraint as well. Eventually the bug will be detected and fixed but at excessive cost. More to the point, the process of building a tightly constrained class model causes the analyst to ferret out detailed project requirements right up front.