Relationships

Relationships between classes are necessary because object-oriented systems are based on the collaboration of objects to accomplish a particular end goal (articulated in the use-cases). Like a network, relationships define the pathways between classes and serve as the messaging media across which objects can communicate. Relationships also define a context between classes prior to instantiation and as objects after instantiation. They then define how the classes of the application function as an integrated whole.

UML is quite rich in its ability to represent relationships between classes. It supports three types of relationships:

  1. Association: The most common type of UML relationship, an association, defines how objects of one class are connected to objects of another class. Without these connections, or associations, no direct messages can pass between objects of these classes in the runtime environment (note that dependencies, discussed below, also indicate a messaging relationship). A simple association for Remulak Productions would be the one defined between a customer and his/her order(s).

  2. Generalization: A generalization defines a lattice of classes such that one class refines—that is, specializes details about—a more general class. The generalized class is often called the superclass, and the specialized class the subclass. All attributes (structure) and operations (behavior) of the generalized class that have public or protected visibility are available to (inherited by) the subclasses. Generalizations are such that any subclass “is a” valid example of the superclass.

    As was pointed out in Chapter 2, an example of a generalization/specialization relationship for Remulak Productions is the Product (superclass) and the subclasses Guitar, SheetMusic, and Supplies. Structure (attributes) and behavior (operations) will be defined for Product and will apply to all of its subclasses. Structure (attributes) and behavior (operations) also will be defined for Guitar, SheetMusic, and Supplies. These attributes and operations are unique to the subclasses and further specialize the definition of a particular instance of Product.

  3. Dependency: A dependency is a relationship in which a change to one class may affect the behavior or state of another class. Typically, dependencies are used in the context of classes to show that one class uses another class as an argument in the signature of an operation.

    Dependencies are more commonly found in package diagrams than in class diagrams. A dependency relationship exists among the three increments for Remulak Productions.

We use association and generalization relationships in the Remulak Productions class diagram.

Establishing Associations

Where do we find associations in the application domain? Explicit associations can be found in the use-cases. However, an early indicator of associations can be found in the event table created during project scoping.

Recall that the use-cases describe the intended uses of the system from the actor's perspective. For an event such as Customer Places Order that is encountered in the dialog for the Process Orders use-case, an explicit association exists between the two classes Customer and Order. When the use-cases were initially created, we had no clear idea what the classes would be. Now that the class creation exercise has been completed, we need to revisit the use-cases in search of associations. Table 5-1 lists the associations for Remulak Productions.

Not all associations are explicitly stated in the use-cases. For example, the association Order is paid by Invoice isn't stated directly in the use-cases. However, it is an implicit association that is necessary to facilitate the messaging described in the pathways of the use-cases.

To construct the class diagram, we draw the classes as rectangles, connect rectangles with a solid line, and place the verb describing the association on the line. In UML, associations are read left to right, top to bottom. However, this isn't always possible, especially with complex diagrams. A small solid triangle can be placed next to the association name to indicate how to read the association. Finally, it isn't absolutely necessary to define an association name, especially if the association is obvious from the classes involved. Figure 5-3 shows an example of a simple association for Remulak Productions.

Figure 5-3. Remulak association example


Table 5-1. Remulak Class Associations
Class Association Class
Customer places Order
Address locates Customer
Order contains OrderLine
Order is paid by Invoice
Order is satisfied by Shipment
Product is specialized by Guitar
Product is specialized by SheetMusic
Product is specialized by Supplies
Product references OrderLine

Notice that the top rectangle contains the class name. A class has three compartments, which define the following:

Compartment 1: Class name, displayed in proper case format

Compartment 2: Attributes (which define the structure of the class)

Compartment 3: Operations (which define the behavior supported by the class)

In many cases, depending on the stage of the project and the reviewing audience, not all of the compartments will be displayed. Attributes and operations are explored in more depth later in this chapter.

Establishing Roles

A role is a UML construct that better qualifies how a particular object will act in its relationship to another class. Roles are optional, but at times they can clarify a class diagram, thereby preventing misinterpretation of what the authors meant (and misinterpretation often happens).

On the association diagram the role is placed next to the class to which it is related. In the case of Remulak Productions, Order could play the role of purchase, while Customer could play the role of purchaser. The next section shows how to diagram this relationship, as well as how to correctly read the association.

A side note for those of you itching to get to the Java code: Roles have a direct impact on the code generation process when you're using a visual modeling tool. In most tools, if you were to generate code from the class diagram expressed in Figure 5-4, the attribute name of the related class would be the role name. In addition, most tools allow a prefix to be appended to the front of the name (e.g., my, the). So for the two classes Customer and Order, we might have the following:

Figure 5-4. Remulak fully adorned Customer/Order association


public class Customer
{
  public Order myPurchase;

  // Other Customer class detail goes here
}

public class Order
{
  public Customer myPurchaser;

  // Other Order class detail goes here
}

If you don't supply a role name, don't worry; most tools will default the attribute name to that of the class name. In our Java example, then, if role names were not supplied on the class diagram, the class-referencing attribute names would be myOrder in the Customer class and myCustomer in the Order class. Again, usually you have some control over the prefix; some people prefer the or an. Some of you might think that the solution presented here is incorrect, for how can you have just one instance of Order in the Customer class? Enter UML's multiplicity.

Establishing Multiplicity

In the modeling of the application, it helps to define the number of possible objects involved in an association. This definition is expressed in the class diagram via the multiplicity property. Multiplicity can take several forms, from very specific (1) to infinite (*). In addition, these designations can be combined to form unique multiplicity statements for the applications; for example, 1..* means “1 or more.”

Figure 5-4 is an example of the Customer/Order association using all of the adornments discussed thus far. The figure is read as follows:

Customer places zero or more Order(s), and Order is acting in the role of purchase.

Order(s) are placed by only one Customer, and Customer is acting in the role of purchaser.

Multiplicity has a direct impact on code generation as well. For the preceding example, with multiplicity the class definition for Customer would change. The reason is that there must be a receptacle to hold the Order objects related to the Customer. It wouldn't do simply to have an attribute defined as type Order because then we could have only one Order related to an instance of Customer. In Chapter 2, with our brief glimpse of Java code, we used an array to handle this situation.

As many of you know, although arrays are very efficient and quite speedy in Java, they are very inflexible for managing relationships between classes. Probably the biggest drawback of an array is the requirement that we define ahead of time how many occurrences there will be. We will get the most flexibility with a Java Collection framework and its implementation of ArrayList. ArrayList is an instance of Vector; however, its methods are not synchronized, so performance is much better.

public class Customer
{
  public ArrayList myPurchase = new ArrayList();

  // Other Customer class detail goes here
}

We need ArrayList because the multiplicity is 0..*.

With roles, it really comes down to a matter of style. Role names can provide good customization for code generation. On the other hand, roles often provide extraneous information that does not add much value to the class diagram, as is the case with the Customer/Order example.

Advanced Associations

Many types of associations are possible—some more complex than others. To appreciate better what UML can offer regarding associations, we next explore more-advanced association types:

  • Aggregation

  • Composition

  • Link

  • Reflexive

  • Qualification

Aggregation and Composition Associations

Aggregation and composition associations model whole/part contexts. In most application domains, a special relationship exists between a collection of classes in which one class clearly exhibits either control or ownership of the others. Simple examples found in the everyday world are an investment portfolio or a book. An investment portfolio is made up of assets (stocks, bonds, other securities); a book is made up of lots of parts (cover, table of contents, chapters, bibliography, index).

Distinguishing aggregation and composition associations from others is important because this distinction will later affect how the application treats the association from an implementation perspective (e.g., in implementing messaging patterns and persistence). Composition is essentially a strong form of aggregation.

Aggregation means that any of the parts may also be related to other wholes. A good example of aggregation is the investment portfolio. For example, Remulak Productions' stock can be part of several individual portfolios. Composition means that any of the parts have only one whole. A book is a good example of composition. The table of contents for this book is associated with this book and this book alone.

For Remulak Productions, composition associations exist between Order and OrderLine. Figure 5-5 shows an example of the Order/OrderLine composition association.

Figure 5-5. Remulak composition example


In UML, composition is shown as a solid diamond and aggregation as a hollow diamond. Aggregation and composition might yield two different solutions, from a program code perspective, depending on the language being used. In Java, the effect would be the same. In C++, an aggregation relationship (the whole) will define its component variables (the parts) by declaring them as “by reference” using a pointer. Composition, on the other hand, will be “by value” by declaring a variable of the class type. Put another way, with composition when the whole is destroyed the parts are destroyed with it. This is not the case with aggregation.

Remember that you do not always have to define an association name, especially when the name is obvious from the context. For example, placing the word contain(s) on each of the three composition associations would be redundant, so it is simply omitted.

Link Associations

Often there is no logical place to define certain information, usually attributes, about the association between two classes. You might need to define a class as a go-between for the actual link between two objects. A link is a runtime version of an association. Note that links are to objects as associations are to classes.

From experience, I know that if an application has an Address class related to another class (Customer in the Remulak case), another type of class likely is needed to hold unique information about that association. So if a Customer can have different shipping and billing addresses, where should the attribute that defines the type of Address exist?

Be careful! An instance of Address might contain a physical shipping address for customer Ryan Maecker, but it might also contain the billing address for customer Mike Richardson. Thus the Address-type attribute won't fit in either Customer or Address. This situation requires what UML calls a link association, or association class, a class that is related to the association of other classes. Perhaps in this class (Role for Remulak Productions), the attributes addressType and dateAssigned can be kept. Implicitly, the class also will contain the information necessary to determine the exact instances of Customer and Address to which these attributes relate. Figure 5-6 shows an example of an association class for Remulak Productions.

Figure 5-6. A Remulak association class


Reflexive Associations

Sometimes an association is needed between two objects of the same class. Called a reflexive association, this type of association is commonly used by many application domains. For Remulak Productions, we want to relate products to other products. This could be beneficial, for example, when an order entry clerk is selling a guitar and wants to recommend some related supplies. To provide this feature, and to model it according to UML, we need to set up a reflexive association on Product. Figure 5-7 shows an example of this association. Notice that the association leaves from and returns to the same class.

Figure 5-7. A Remulak reflexive association


Qualification Associations

When the class diagram is created, no distinction is made regarding how the association is traversed. Rather, one class is viewed as simply having access to all of the possible associations (links in runtime between objects) to their related classes. In some cases it might be important enough in the domain to specify how the association will be traversed. Qualifiers provide this ability in UML. A qualifier allows a set of related objects to be returned on the basis of the qualification of some specific attribute(s).

For Remulak Productions, a qualifier could be placed, if needed, on the association between Customer and Order, as shown in Figure 5-8. The source object (Customer) and the qualifier's attributes (orderId) together yield a target set of object(s) (Order). In the case of Remulak Productions, either nothing or one Order object will be returned.

Figure 5-8. A Remulak qualified association


For the class diagram for Remulak Productions (outlined later in this chapter), we will diagram no qualified associations.

Generalization

Recall from earlier in the chapter that generalization is a way to depict a lattice of classes and to portray the fact that one class can be made to hold both structure (attributes) and behavior (operations) that apply to one or more specialized classes. These specialized classes can then add additional structure and behavior as necessary to portray their unique characteristics. Every instance of the specialized class also “is an” instance of the generalized class.

For Remulak Productions, a generalization/specialization relationship exists between Product and the classes Guitar, SheetMusic, and Supplies. Product is the generalized class, and the other three are specializations of Product. Common components will be defined in Product that will apply to all of the specialized classes. Figure 5-9 shows this generalization/specialization association.

Figure 5-9. A Remulak generalization/specialization class diagram


..................Content has been hidden....................

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