Relationships
In the Interaction diagrams, we began to look at how classes communicate with one another. Now, we'll focus on the relationships between the classes. A relationship is a semantic connection between classes. It allows one class to know about the attributes, operations, and relationships of another class. In order for one class to send a message to another on a Sequence or Collaboration diagram, there must be a relationship between the two classes.
Relationships In this module, we'll take a look at the different types of relationships that can be established between classes and between packages. We'll discuss the implications of each type of relationship and explore how to add the relationship to your Rose model. –Adding association, dependency, aggregation, and generalization relationships to a Rose model through a Class diagram –Adding relationship names, stereotypes, role names, static relationships, friend relationships, qualifiers, link elements, and constraints –Setting multiplicity, export control, and containment
Types of Relationships There are five types of relationships you can set up between classes: associations, dependencies, aggregations, realizes relationships, and generalizations.
Types of Relationships Associations are semantic connections between classes. They are drawn on a Class diagram with a single line,
Types of Relationships When an association connects two classes, as in the above example, each class can send messages to the other in a Sequence or a Collaboration diagram. Associations can be bidirectional, as shown above, or unidirectional. In UML, bidirectional associations are drawn either with arrowheads on both ends or without arrowheads altogether. Unidirectional associations contain one arrowhead showing the direction of the navigation. With an association, Rose will place attributes in the classes. For example, if there is an association relationship between a Flight class and a Customer class, Rose would place a Customer attribute inside Flight to let the flight know who the passengers are, and a Flight attribute inside Customer to let the customer know which flight they are on.
Bidirectional association
The Flight class knows about the public attributes and operations of Customer, and the Customer class knows about the public attributes and operations of Flight. On a Sequence diagram, therefore, Flight can send messages to Customer, and Customer can send messages to Flight.
Unidirectional associations
In this case, the Flight class knows about the public attributes and operations of Customer, but Customer does not know about the public attributes and operations of Flight. Messages on a Sequence or Collaboration diagram can be sent by Flight and received by Customer, but cannot be sent by Customer. You can determine the direction of an association by looking at the Sequence and Collaboration diagrams. If every message on the Interaction diagrams is sent by Flight and received by Customer, there is a unidirectional relationship from Flight to Customer. If there is even one message from Customer to Flight, you will need a bidirectional relationship.
Unidirectional associations Unidirectional relationships can help you identify classes that are good candidates for reuse. If the association between Flight and Customer is bidirectional, each class needs to know about the other; neither class can, therefore, be reused without the other. But assume instead that there is a unidirectional relationship from Flight to Customer. Flight needs to know about Customer, so it can't be reused without Customer. However, Customer doesn't need to know about Flight, so Customer can be easily reused. Any class that has many unidirectional relationships coming out of it is hard to reuse; any class that has only unidirectional relationships coming into it is easy to reuse,
Unidirectional associations
Associations When you generate code for a bidirectional association, Rose will generate attributes in each class. In our Flight and Customer example, Rose will place a Flight attribute inside Customer, and a Customer attribute inside Flight. If, instead, we have a unidirectional association, Rose will place a Customer attribute inside Flight, but not a Flight attribute inside Customer.
Using Web Association Stereotypes With the inclusion of web modeling, Rose now supports four stereotypes for associations. These are the link, submit, build, and redirect stereotypes. The link stereotype is used to show a hypertext link between two client pages or from a client page to a server page. It is represented on a Class diagram as a unidirectional association with a stereotype of >:
Using Web Association Stereotypes
The submit stereotype is used when a form sends the information in its fields to a server page for processing. This submittal of information is shown on a Class diagram as a unidirectional association relationship with a stereotype of >.
Using Web Association Stereotypes
The build stereotype is used when a server page builds a client page. Once the client page has been built, it can be displayed on the client browser. The relationship shows which server page builds which client page. It is shown on a class diagram as a unidirectional relationship with a stereotype of >:
Using Web Association Stereotypes
Finally, the redirect stereotype is used to show one page passing processing control to another page. A redirect relationship is shown as a unidirectional association with a stereotype of >:
Using Web Association Stereotypes
Dependencies A dependency relationship shows that a class references another class. Therefore, a change in the referenced class specification may impact the using class. When there is a dependency between two classes, Rose does not add any attributes to the classes for the relationship, which is one of the differences between an association and a dependency.
Dependencies
When we generate code for these two classes, attributes will not be added to either class for the relationship. The implication here is that Flight will need some other way to know that Customer exists. The direction of the arrow indicates that Flight depends on Customer. In other words, there is a Sequence or Collaboration diagram in which Flight sends a message to Customer. Had there bee a regular association between these two, Flight would have a Customer attribute. To send a message to Customer, Flight would just look at its own Customer attribute.
Dependencies With a dependency, however, Flight won't have a Customer attribute. It therefore has to find out about Customer some other way. There are three ways it can know about Customer. Customer could be global, in which case Flight would know it exists. Or, Customer could be instantiated as a local variable inside an operation of Flight. Finally, Customer could be passed in as a parameter to some operation inside Flight. When there is a dependency, one of these three approaches must be taken.
Dependencies We may need to add an argument to an operation of Flight.
Package Dependencies Dependencies can be drawn between packages as well as classes. A package dependency, like a class dependency, is drawn as a dashed arrow.
Package Dependencies A package dependency from package A to package B suggests that some class in package A has a unidirectional relationship to some class in package B. In other words, some class in A needs to know about some class in B. This has reuse implications. If our dependencies look like this, package A depends on package B. Therefore, we can't just pick up package A and reuse it in another application. We would also have to pick up B and reuse it. Package B, on the other hand, is easy to reuse because it doesn't depend on anything else.
Package Dependencies You can find package dependencies by examining the relationships on your Class diagram. If two classes from different packages have a relationship, their packages must have a relationship as well.
Package Dependencies As you are creating package dependencies, try to avoid circular dependencies whenever possible. A circular dependency looks like Figure
Package Dependencies This suggests that some class in A needs to know about some class in B, while some class in B needs to know about some class in A. In this case, neither package can be easily reused, and a change to one package may affect the other. We've lost some of the benefits of packaging classes with this approach—the packages are too interdependent. To break circular dependencies, you can split apart one package into two. In our example, we can take the classes in B that A depends on, and move them to another package we'll call C. Now our package dependencies look like this:
Package Dependencies
Aggregations An aggregation is a stronger form of association. An aggregation is a relationship between a whole and its parts. For example, a FlightList might be made up of Flights. In UML, an aggregation is shown as a line connecting the two classes, with a diamond next to the class representing the whole.
Aggregations One class may have several aggregation relationships with other classes. For example, a Car class might have relationships to its many parts.
Generalizations A generalization is an inheritance relationship between two model elements such as classes, actors, use cases, and packages. It allows one class to inherit the public and protected attributes and operations of another class. For example, we may have the relationship shown in Figure
Generalizations