he UML association is a concept that is often misunderstood. The most common misperception is that an association is the same as a pointer, or maybe two pointers, in a program. UML associations are much more powerful than that.
This article will explain exactly what UML associations are and the ways in which you can implement them. The implementation examples are written in Java, but you can perform a translation to another programming language easily. The code examples in this article were all completely generated by the UML/OCL tool called Octopus, which can be downloaded from http://www.klasse.nl/english/research/octopus-intro.html. The code examples themselves can be downloaded here or from the link in the left-hand column.
The Difference Between Associations and Pointers
In a programming language a pointer can be used to reference another element. That other element may be a single object or a collection of objects (for instance, a list or set). The referenced element is completely unaware of the fact that some object holds a reference to it. Furthermore, the object holding the reference may freely distribute the reference amongst other objects.
In short, a pointer is simply information on how to find an element, comparable to a Web site address. If I were to have the address of a Web site that holds, for instance, CIA secrets, the CIA need not be aware that I have that address. And I can share that address with anyone and the CIA need never know.
A UML association is, like a pointer, a reference to another element or a collection of elements, but in this case the other element is aware of the reference. Using a UML association, the CIA would know who I am and that I have its Web site address. Most associations are two-way navigable, that is, if object A has a reference to object B, then by definition object B has a reference to object A. Later in this article, we will discuss one-way navigable associations.
|Author's Note: Besides generating all the code that implements associations, Octopus is capable of generating a user interface prototype and an XML storage facility from your UML model. This allows you to run the application and create instances of the classes in the model.
Associations are "Marriages"
UML associations represent relationships. Therefore, we have found that the best way to explain what an association is, is by comparison with a marriage. Figure 1 shows a class diagram with the classes Man and Woman, and an association between these classes. Also shown are two example instances of this configuration: a marriage between John and Mary, and one between Bob and Olivia.
|Figure 1. Marriages: This class diagram shows two examples of a simple association between a Man and Woman class.|
Any two objects that are linked through an association are "married," just like John and Mary. Such a marriage has a number of characteristics, which we call the ABACUS rules. The characteristics that make up ABACUS (and compose the acronym) are:
- Awareness: Both objects are aware of the fact that the relationship exists.
- Boolean existence: If the partners agree to a divorce, the relationship (in UML called the link) is dissolved completely.
- Agreement: Both objects have to agree with the relationship; they need to say "I do."
- Cascaded deletion: If one of the partners dies, the link is dissolved as well.
- USe of rolenames: An object may refer to its partner using the role name provided with the association: "my husband" or "my wife."
So far so good, but associations may have different multiplicities than the one-to-one version in a monogamous marriage. What's happens when one of the association ends has a multiplicity that is higher than one? In that case, clearly, you have some kind of polygamous marriage (see Figure 2).
|Figure 2. Multiplicity: The concept of a polygamous marriage serves as an easy-to-grasp example of multiplicity in UML associations.|
Still, all of the ABACUS rules for associations apply. As in the monogamous marriage, the objects at both sides of the relationship are aware of the fact that the relationship exists. However, an object at the plural side need not be aware of all the other objects that are in this relationship. In this example, John knows that he is married to Mary. He knows that it is a polygamous marriage, but he need not know Mary's other husbands. The same holds for Bob. On the other hand, Mary knows all of her husbands, both Bob and John.
Likewise, both Bob and John may still refer to Mary as "my wife," and Mary may refer to the group (collection) consisting of John and Bob as "my husbands." But referring to a single element in this group, for instance to Bob, becomes harder. Mary needs to use some selection mechanism on her collection of husbands, for instance based on the name of the husband. Written in OCL, Mary would need to use an expression like self.myHusbands->select(name = 'Bob'). If Mary and Bob decide to divorce, only the link between them is dissolved; the link between Mary and John remains intact.
The case where both association ends have a multiplicity greater than one, is could be modeled as a kind of group marriage, where John might be married to three women: Linda, Olivia, and Mary, and Olivia might be married to two men, as shown in Figure 3. All the characteristics of associations hold in this case as well.
|Figure 3. Complex Multiplicity: Five polygamous persons demonstrate the ability of associations to be multiple on both ends.|
Sets, Ordered Sets, Bags, and Sequences
UML associations are much more fun than our example has demonstrated thus far. The UML offers a choice in the type of collection used for an association end with a multiplicity greater than one. You may choose one of the following four types:
- Set: Every element may be present in the collection only once. This is the default collection type for association ends with a multiplicity larger than one.
- Ordered Set: A set in which the elements are ordered. There is an index number for each element. Note that the elements are not sorted, that is, an element with a lower index number is not in any way larger or smaller than one with a higher index. An association end with this type is indicated in the diagram by adding the marking <ordered>.
- Bag: An element may be in the collection more than once. In the marriage example this means that, for instance, Mary may be married to John twice. Note that if one end of an association has this type, than the other end must be either a bag or a sequence. The type is indicated in the diagram by <bag>.
- Sequence: A bag in which the elements are ordered. It is indicated in the diagram by <sequence> or <seq>. If one end of an association has this type, than the other end must be either a bag or a sequence.
What are the effects of choosing a different collection type for an association end? Let us first stress that the ABACUS rules must hold, whatever type you choose. The type of the association end is relevant only when an element is added to the relationship, and this is very important for the way associations are implemented.
In the diagram for the group marriage (Figure 3) the end is marked "my wives" as an ordered set. This means that the implementer of the addWife operation in the class Man that adds a woman to the ordered set must decide how to order the set of wives. The simplest option is to add the "new wife" as the last in the ordered set. Also, the implementer of addWife must make sure that the new wife is not already present in the list of wives. The OrderedSet type does not allow this.