unday, November 18, 2012
UML Class Diagram Relationships, Aggregation, Composition
There are five key relationships between classes in a UML class diagram :
dependency, aggregation, composition, inheritance and realization.
These five relationships are depicted in the following diagram:
The above relationships are read as follows:
Now, if class A stored the reference to class B for later use we would have a different relationship called Aggregation. A more common and more obvious example of Aggregation would be via setter injection:
Aggregation is the weaker form of object containment (one object contains other objects). The stronger form is called Composition. In Composition the containing object is responsible for the creation and life cycle of the contained object (either directly or indirectly). Following are a few examples of Composition. First, via member initialization:
Second, via constructor initialization:
Third, via lazy init (example revised 02 Mar 2014 to completely hide reference to B):
Realization is also straighforward in Java and deals with implementing an interface:
![]() |
UML Class Relationships |
- Dependency : class A uses class B
- Aggregation : class A has a class B
- Composition : class A owns a class B
- Inheritance : class B is a Class A (or class A is extended by class B)
- Realization : class B realizes Class A (or class A is realized by class B)
Dependency is represented when a reference to one class is
passed in as a method parameter to another class. For example, an
instance of class B is passed in to a method of class A:
1
2
3
| public class A { public void doSomething(B b) { |
Now, if class A stored the reference to class B for later use we would have a different relationship called Aggregation. A more common and more obvious example of Aggregation would be via setter injection:
1
2
3
4
5
| public class A { private B _b; public void setB(B b) { _b = b; } |
Aggregation is the weaker form of object containment (one object contains other objects). The stronger form is called Composition. In Composition the containing object is responsible for the creation and life cycle of the contained object (either directly or indirectly). Following are a few examples of Composition. First, via member initialization:
1
2
3
| public class A { private B _b = new B(); |
Second, via constructor initialization:
1
2
3
4
5
6
7
| public class A { private B _b; public A() { _b = new B(); } // default constructor |
Third, via lazy init (example revised 02 Mar 2014 to completely hide reference to B):
1
2
3
4
5
6
7
8
9
10
| public class A { private B _b; public void doSomethingUniqueToB() { if ( null == _b) { _b = new B(); } return _b.doSomething(); } // doSomethingUniqueToB() |
Inheritance is a fairly straightforward relationship to depict in Java:
1
2
3
4
5
6
7
8
9
10
11
| public class A { ... } // class A public class B extends A { .... } // class B |
Realization is also straighforward in Java and deals with implementing an interface:
1
2
3
4
5
6
7
8
9
10
------------------------- ------ Structural Dgms in general As I have said, structure diagrams show the static structure of the system being modeled. focusing on the elements of a system, irrespective of time. Static structure is conveyed by showing the types and their instances in the system. Besides showing system types and their instances, structure diagrams also show at least some of the relationships among and between these elements and potentially even show their internal structure. Structure diagrams are useful throughout the software lifecycle for a variety of team members. In general, these diagrams allow for design validation and design communication between individuals and teams. For example, business analysts can use class or object diagrams to model a business's current assets and resources, such as account ledgers, products, or geographic hierarchy. Architects can use the component and deployment diagrams to test/verify that their design is sound. Developers can use class diagrams to design and document the system's coded (or soon-to-be-coded) classes. The class diagram in particularUML 2 considers structure diagrams as a classification; there is no diagram itself called a "Structure Diagram." However, the class diagram offers a prime example of the structure diagram type, and provides us with an initial set of notation elements that all other structure diagrams use. And because the class diagram is so foundational, the remainder of this article will focus on the class diagram's notation set. By the end of this article you should have an understanding of how to draw a UML 2 class diagram and have a solid footing for understanding other structure diagrams when we cover them in later articles.The basicsAs mentioned earlier, the purpose of the class diagram is to show the types being modeled within the system. In most UML models these types include:
Class nameThe UML representation of a class is a rectangle containing three compartments stacked vertically, as shown in Figure 1. The top compartment shows the class's name. The middle compartment lists the class's attributes. The bottom compartment lists the class's operations. When drawing a class element on a class diagram, you must use the top compartment, and the bottom two compartments are optional. (The bottom two would be unnecessary on a diagram depicting a higher level of detail in which the purpose is to show only the relationship between the classifiers.) Figure 1 shows an airline flight modeled as a UML class. As we can see, the name is Flight, and in the middle compartment we see that the Flight class has three attributes: flightNumber, departureTime, and flightDuration. In the bottom compartment we see that the Flight class has two operations: delayFlight and getArrivalTime.Figure 1: Class diagram for the class FlightClass attribute listThe attribute section of a class (the middle compartment) lists each of the class's attributes on a separate line. The attribute section is optional, but when used it contains each attribute of the class displayed in a list format. The line uses the following format:name : attribute type flightNumber : Integer Table 1: The Flight class's attribute names with their associated types
Sometimes it is useful to show on a class diagram that a particular attribute has a default value. (For example, in a banking account application a new bank account would start off with a zero balance.) The UML specification allows for the identification of default values in the attribute list section by using the following notation: name : attribute type = default value balance : Dollars = 0 Figure 2: A Bank Account class diagram showing the balance attribute's value defaulted to zero dollarsClass operations listThe class's operations are documented in the third (lowest) compartment of the class diagram's rectangle, which again is optional. Like the attributes, the operations of a class are displayed in a list format, with each operation on its own line. Operations are documented using the following notation:name(parameter list) : type of value returned Table 2: Flight class's operations mapped from Figure 3
delayFlight(numberOfMinutes : Minutes) : Date. ] When an
operation has parameters, they are put inside the operation's
parentheses; each parameter uses the format "parameter name : parameter
type".Figure 3: The Flight class operations parameters include the optional "in" markingInheritanceA very important concept in object-oriented design, inheritance, refers to the ability of one class (child class) to inherit the identical functionality of another class (super class), and then add new functionality of its own. (In a very non-technical sense, imagine that I inherited my mother's general musical abilities, but in my family I'm the only one who plays electric guitar.) To model inheritance on a class diagram, a solid line is drawn from the child class (the class inheriting the behavior) with a closed, unfilled arrowhead (or triangle) pointing to the super class. Consider types of bank accounts: Figure 4 shows how both CheckingAccount and SavingsAccount classes inherit from the BankAccount class.Figure 4: Inheritance is indicated by a solid line with a closed, unfilled arrowhead pointing at the super classFigure 5: An example of inheritance using tree notationAbstract classes and operationsThe observant reader will notice that the diagrams in Figures 4 and 5 use italicized text for the BankAccount class name and withdrawal operation. This indicates that the BankAccount class is an abstract class and the withdrawal method is an abstract operation. In other words, the BankAccount class provides the abstract operation signature of withdrawal and the two child classes of CheckingAccount and SavingsAccount each implement their own version of that operation.However, super classes (parent classes) do not have to be abstract classes. It is normal for a standard class to be a super class. AssociationsWhen you model a system, certain objects will be related to each other, and these relationships themselves need to be modeled for clarity. There are five types of associations. I will discuss two of them — bi-directional and uni-directional associations — in this section, and I will discuss the remaining three association types in the Beyond the basics section. Please note that a detailed discussion of when to use each type of association is beyond the scope of this article. Instead, I will focus on the purpose of each association type and show how the association is drawn on a class diagram.Bi-directional (standard) associationAn association is a linkage between two classes. Associations are always assumed to be bi-directional; this means that both classes are aware of each other and their relationship, unless you qualify the association as some other type. Going back to our Flight example, Figure 6 shows a standard kind of association between the Flight class and the Plane class.Figure 6: An example of a bi-directional association between a Flight class and a Plane classFor those wondering what the potential multiplicity values are for the ends of associations, Table 3 below lists some example multiplicity values along with their meanings. Table 3: Multiplicity values and their indicators
Uni-directional associationIn a uni-directional association, two classes are related, but only one class knows that the relationship exists. Figure 7 shows an example of an overdrawn accounts report with a uni-directional association.Figure 7: An example of a uni-directional association: The OverdrawnAccountsReport class knows about the BankAccount class, but the BankAccount class does not know about the associationPackagesInevitably, if you are modeling a large system or a large area of a business, there will be many different classifiers in your model. Managing all the classes can be a daunting task; therefore, UML provides an organizing element called a package. Packages enable modelers to organize the model's classifiers into namespaces, which is sort of like folders in a filing system. Dividing a system into multiple packages makes the system easier to understand, especially if each package represents a specific part of the system. [Note: Packages are great for organizing your model's classes, but it's important to remember that your class diagrams are supposed to easily communicate information about the system being modeled. In cases where your packages have lots of classes, it is better to use multiple topic-specific class diagrams instead of just producing one large class diagram.]There are two ways of drawing packages on diagrams. There is no rule for determining which notation to use, except to use your personal judgement regarding which is easiest to read for the class diagram you are drawing. Both ways begin with a large rectangle with a smaller rectangle (tab) above its upper left corner, as seen in Figure 8. But the modeler must decide how the package's membership is to be shown, as follows:
Figure 8: An example package element that shows its members inside the package's rectangle boundariesFigure 9: An example package element showing its membership via connected linesImportance of understanding the basicsIt is more important than ever in UML 2 to understand the basics of the class diagram. This is because the class diagram provides the basic building blocks for all other structure diagrams, such as the component or object diagrams (just to name a few).Beyond the basicsAt this point, I have covered the basics of the class diagram, but do not stop reading yet! In the following sections, I will address more important aspects of the class diagram that you can put to good use. These include interfaces, the three remaining types of associations, visibility, and other additions in the UML 2 specification.InterfacesEarlier in this article, I suggested that you think of classifiers simply as classes. In fact, a classifier is a more general concept, which includes data types and interfaces.A complete discussion of when and how to use data types and interfaces effectively in a system's structure diagrams is beyond the scope of this article. So why do I mention data types and interfaces here? There are times when you might want to model these classifier types on a structure diagram, and it is important to use the proper notation in doing so, or at least be aware of these classifier types. Drawing these classifiers incorrectly will likely confuse readers of your structure diagram, and the ensuing system will probably not meet requirements. A class and an interface differ: A class can have an actual instance of its type, whereas an interface must have at least one class to implement it. In UML 2, an interface is considered to be a specialization of a class modeling element. Therefore, an interface is drawn just like a class, but the top compartment of the rectangle also has the text "«interface»", as shown in Figure 10. [Note: When drawing a class diagram it is completely within UML specification to put «class» in the top compartment of the rectangle, as you would with «interface»; however, the UML specification says that placing the "class" text in this compartment is optional, and it should be assumed if «class» is not displayed.] Figure 10: Example of a class diagram in which the Professor and Student classes implement the Person interfaceMore associationsAbove, I discussed bi-directional and uni-directional associations. Now I will address the three remaining types of associations.Association classIn modeling an association, there are times when you need to include another class because it includes valuable information about the relationship. For this you would use an association class that you tie to the primary association. An association class is represented like a normal class. The difference is that the association line between the primary classes intersects a dotted line connected to the association class. Figure 11 shows an association class for our airline industry example.Figure 11: Adding the association class MileageCreditAggregationAggregation is a special type of association used to model a "whole to its parts" relationship. In basic aggregation relationships, the lifecycle of a part class is independent from the whole class's lifecycle.For example, we can think of Car as a whole entity and Car Wheel as part of the overall Car. The wheel can be created weeks ahead of time, and it can sit in a warehouse before being placed on a car during assembly. In this example, the Wheel class's instance clearly lives independently of the Car class's instance. However, there are times when the part class's lifecycle is not independent from that of the whole class — this is called composition aggregation. Consider, for example, the relationship of a company to its departments. Both Company and Departments are modeled as classes, and a department cannot exist before a company exists. Here the Department class's instance is dependent upon the existence of the Company class's instance. Let's explore basic aggregation and composition aggregation further. Basic aggregation An association with an aggregation relationship indicates that one class is a part of another class. In an aggregation relationship, the child class instance can outlive its parent class. To represent an aggregation relationship, you draw a solid line from the parent class to the part class, and draw an unfilled diamond shape on the parent class's association end. Figure 12 shows an example of an aggregation relationship between a Car and a Wheel. Figure 12: Example of an aggregation associationThe composition aggregation relationship is just another form of the aggregation relationship, but the child class's instance lifecycle is dependent on the parent class's instance lifecycle. In Figure 13, which shows a composition relationship between a Company class and a Department class, notice that the composition relationship is drawn like the aggregation relationship, but this time the diamond shape is filled. Figure 13: Example of a composition relationshipReflexive associationsWe have now discussed all the association types. As you may have noticed, all our examples have shown a relationship between two different classes. However, a class can also be associated with itself, using a reflexive association. This may not make sense at first, but remember that classes are abstractions. Figure 14 shows how an Employee class could be related to itself through the manager/manages role. When a class is associated to itself, this does not mean that a class's instance is related to itself, but that an instance of the class is related to another instance of the class.Figure 14: Example of a reflexive association relationshipVisibilityIn object-oriented design, there is a notation of visibility for attributes and operations. UML identifies four types of visibility: public, protected, private, and package.The UML specification does not require attributes and operations visibility to be displayed on the class diagram, but it does require that it be defined for each attribute or operation. To display visibility on the class diagram, you place the visibility mark in front of the attribute's or operation's name. Though UML specifies four visibility types, an actual programming language may add additional visibilities, or it may not support the UML-defined visibilities. Table 4 displays the different marks for the UML-supported visibility types. Table 4: Marks for UML-supported visibility types
Figure 15: A BankAccount class that shows the visibility of its attributes and operationsUML 2 additionsNow that we have covered the basics and the advanced topics, we will cover some of the new notations added to the class diagram from UML 1.x.InstancesWhen modeling a system's structure it is sometimes useful to show example instances of the classes. To model this, UML 2 provides the instance specification element, which shows interesting information using example (or real) instances in the system.The notation of an instance is the same as a class, but instead of the top compartment merely having the class's name, the name is an underlined concatenation of: Instance Name : Class Name Donald : Person Figure 16: An example instance of a Plane class (only the interesting attribute values are shown)Figure 17: An example of Figure 6 using instances instead of classesRolesModeling the instances of classes is sometimes more detailed than one might wish. Sometimes, you may simply want to model a class's relationship at a more generic level. In such cases, you should use the role notation. The role notation is very similar to the instances notation. To model a class's role, you draw a box and place the class's role name and class name inside as with the instances notation, but in this case you do not underline the words. Figure 18 shows an example of the roles played by the Employee class described by the diagram at Figure 14. In Figure 18, we can tell, even though the Employee class is related to itself, that the relationship is really between an Employee playing the role of manager and an Employee playing the role of team member.Figure 18: A class diagram showing the class in Figure 14 in its different rolesInternal StructuresOne of the more useful features of UML 2 structure diagrams is the new internal structure notation. It allows you to show how a class or another classifier is internally composed. This was not possible in UML 1.x, because the notation set limited you to showing only the aggregation relationships that a class had. Now, in UML 2, the internal structure notation lets you more clearly show how that class's parts relate to each other.Let's look at an example. In Figure 18 we have a class diagram showing how a Plane class is composed of four engines and two control software objects. What is missing from this diagram is any information about how airplane parts are assembled. From the diagram in Figure 18, you cannot tell if the control software objects control two engines each, or if one control software object controls three engines and the other controls one engine. Figure 19: A class diagram that only shows relationships between the objectsFigure 20: An example internal structure of a Plane classConclusionThere are at least two important reasons for understanding the class diagram. The first is that it shows the static structure of classifiers in a system; the second reason is that the diagram provides the basic notation for other structure diagrams prescribed by UML. Developers will think the class diagram was created specially for them; but other team members will find them useful, too. Business analysts can use class diagrams to model systems from the business perspective. As we will see in other articles in this series on UML basics, other diagrams — including the activity, sequence, and statechart diagrams — refer to the classes modeled and documented on the class diagram.Next in this series on UML bt supported within comments. | public interface A { ... } // interface A public class B implements A { ... } // class B |
No comments:
Post a Comment