Search This Blog

Monday, June 10, 2013

Class diagram=Basis

UML 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 basics

As 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:

  • a class
  • an interface
  • a data type
  • a component.

UML uses a special name for these types: "classifiers." Generally, you can think of a classifier as a class, but technically a classifier is a more general term that refers to the other three types above as well.

Class name

The 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 Flight
Class diagram for the class Flight

Class attribute list

The 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


Continuing with our Flight class example, we can describe the class's attributes with the attribute type information, as shown in Table 1.

Table 1: The Flight class's attribute names with their associated types

Attribute Name Attribute Type
flightNumber Integer
departureTime Date
flightDuration Minutes

In business class diagrams, the attribute types usually correspond to units that make sense to the likely readers of the diagram (i.e., minutes, dollars, etc.). However, a class diagram that will be used to generate code needs classes whose attribute types are limited to the types provided by the programming language, or types included in the model that will also be implemented in the system.

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


For example:

balance : Dollars = 0


Showing a default value for attributes is optional; Figure 2 shows a Bank Account class with an attribute called balance, which has a default value of 0.

Figure 2: A Bank Account class diagram showing the balance attribute's value defaulted to zero dollars
A Bank Account class diagram showing the balance attribute's value defaulted to zero dollars

Class operations list

The 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


The Flight class's operations are mapped in Table 2 below.

Table 2: Flight class's operations mapped from Figure 3

Operation Name Parameters Return Value Type
delayFlight
Name Type
numberOfMinutes Minutes
N/A
getArrivalTime N/A Date

Figure 3 shows that the delayFlight operation has one input parameter — numberOfMinutes — of the type Minutes. However, the delayFlight operation does not have a return value. [Note: The delayFlight does not have a return value because I made a design decision not to have one. One could argue that the delay operation should return the new arrival time, and if this were the case, the operation signature would appear as 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" marking
 The Flight class operations parameters include the optional 'in' marking

When documenting an operation's parameters, you may use an optional indicator to show whether or not the parameter is input to, or output from, the operation. This optional indicator appears as an "in" or "out" as shown in the operations compartment in Figure 3. Typically, these indicators are unnecessary unless an older programming language such as Fortran will be used, in which case this information can be helpful. However, in C++ and Java, all parameters are "in" parameters and since "in" is the parameter's default type according to the UML specification, most people will leave out the input/output indicators.

Inheritance

A 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 class
Inheritance indicated by a solid line with a closed, unfilled arrowhead pointing at the super class

In Figure 4, the inheritance relationship is drawn with separate lines for each subclass, which is the method used in IBM Rational Rose and IBM Rational XDE. However, there is an alternative way to draw inheritance called tree notation. You can use tree notation when there are two or more child classes, as in Figure 4, except that the inheritance lines merge together like a tree branch. Figure 5 is a redrawing of the same inheritance shown in Figure 4, but this time using tree notation.

Figure 5: An example of inheritance using tree notation
Example of inheritance using tree notation

Abstract classes and operations

The 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.

Associations

When 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) association

An 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 class
An example of a bi-directional association between a Flight class and a Plane class

A bi-directional association is indicated by a solid line between the two classes. At either end of the line, you place a role name and a multiplicity value. Figure 6 shows that the Flight is associated with a specific Plane, and the Flight class knows about this association. The Plane takes on the role of "assignedPlane" in this association because the role name next to the Plane class says so. The multiplicity value next to the Plane class of 0..1 means that when an instance of a Flight exists, it can either have one instance of a Plane associated with it or no Planes associated with it (i.e., maybe a plane has not yet been assigned). Figure 6 also shows that a Plane knows about its association with the Flight class. In this association, the Flight takes on the role of "assignedFlights"; the diagram in Figure 6 tells us that the Plane instance can be associated either with no flights (e.g., it's a brand new plane) or with up to an infinite number of flights (e.g., the plane has been in commission for the last five years).

For 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

Potential Multiplicity Values
Indicator Meaning
0..1 Zero or one
1 One only
0..* Zero or more
* Zero or more
1..* One or more
3 Three only
0..5 Zero to Five
5..15 Five to Fifteen

Uni-directional association

In 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 association
An example of a uni-directional association

A uni-directional association is drawn as a solid line with an open arrowhead (not the closed arrowhead, or triangle, used to indicate inheritance) pointing to the known class. Like standard associations, the uni-directional association includes a role name and a multiplicity value, but unlike the standard bi-directional association, the uni-directional association only contains the role name and multiplicity value for the known class. In our example in Figure 7, the OverdrawnAccountsReport knows about the BankAccount class, and the BankAccount class plays the role of "overdrawnAccounts." However, unlike a standard association, the BankAccount class has no idea that it is associated with the OverdrawnAccountsReport. [Note: It may seem strange that the BankAccount class does not know about the OverdrawnAccountsReport class. This modeling allows report classes to know about the business class they report, but the business classes do not know they are being reported on. This loosens the coupling of the objects and therefore makes the system more adaptive to changes.]

Packages

Inevitably, 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:

  • If the modeler decides to show the package's members within the large rectangle, then all those members need to be placed within the rectangle. [Note: It's important to understand that when I say "all those members," I mean only the classes that the current diagram is going to show. A diagram showing a package with contents does not need to show all its contents; it can show a subset of the contained elements according to some criterion, which is not necessarily all the package's classifiers.] Also the package's name needs to be placed in the package's smaller rectangle (as show n in Figure 8).
  • If the modeler decides to show the package's members outside the large rectangle then all the members that will be shown on the diagram need to be placed outside the rectangle. To show what classifiers belong to the package, a line is drawn from each classifier to a circle that has a plus sign inside the circle attached to the package (Figure 9).

Figure 8: An example package element that shows its members inside the package's rectangle boundaries
An example package element that shows its members inside the package's rectangle boundaries

Figure 9: An example package element showing its membership via connected lines
Figure 9 caption describes image

Importance of understanding the basics

It 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).

 

No comments:

Post a Comment

Blog Archive

About Me

An seasoned developer, architect and with some Team Leading exposure, offering full project life cycle experiences within multi cultural, multi National environments and within differing business streams and all primarily on a .Net platform.