A Picture Can Save a Thousand Words: UML Class Diagrams and Java
Introduction
Welcome to what I hope will be a gentle and useful introduction to UML and object modeling from a Java programmer's perspective. Although it's tempting to spend time considering the history and philosophy behind UML, let's get straight down to business and look at how UML represents classes; we can do historical and philosophical stuff as we go.
In Java, we declare two public classes using the following code:
public class Person{} public class Organization{}
We have to declare each public class in a separate file with the same name as the class and an extension of .java.
In contrast, UML is a graphical modeling "language," and it represents a class as a rectangle with the class' name inside. We can show several classes on a single class diagram (see Figure 1).
Figure 1 A very simple class diagram showing two classes.
Although not blood-chillingly exciting, the figure shows a single picture that represents the contents of two source code files. UML class diagrams are very good for communicating the overall structure of a number of classes and the dependencies between them in a single picture. For example, many books on analysis and design patterns use UML class diagrams to show the structure of the classes participating in the patterns they describe.
Historical Note
For those who are interested: The use of a rectangle to represent classes is as a result of the U in UML. Before the first version of UML, each object-modeling guru defined his own set of symbols. Some used blobs for classes, others circles, others rectangles with rounded corners. The result was a good deal of confusion, debate, and distraction. Then three of the gurusGrady Booch, James Raumbaugh and Ivar Jacobsongot together at Rational Corporation and agreed to "unify" their notations. UML was created, and the notation wars were effectively over.
Obviously, empty classes are not very interesting. So let's start to add some simple instance variables and methods to our Person class. Here is a compactly formatted version in Java, omitting all Javadoc comments.
public class Person { private String name; private String socialSecurityNumber; private Date dateOfBirth; private String emailAddress; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSocialSecurityNumber() { return socialSecurityNumber; } public void setSocialSecurityNumber(String socialSecurityNumber) { this.socialSecurityNumber = socialSecurityNumber; } public Date getDateOfBirth() { return dateOfBirth; } public void setDateOfBirth(Date dateOfBirth) { this.dateOfBirth = dateOfBirth; } public int calcAgeInYears() {/*not implemented yet*/return 0;} }
Figure 2 shows the same in UML. As we can see, UML uses + and - symbols to indicate the public and private modifiers, respectively. UML class diagrams show only the signature of the operations with the type of the attribute or the result of the operation at the end of the line after a colon.
Figure 2 Attributes and methods in UML.
It is a littler easier to see the list of attributes and methods in Figure 2 than it is in the equivalent Java source code because the implementation of the methods are not shown. However, when working with UML, it is common to omit or hide most of the detail so that it is easier to get a feel for the overall structure of the class. For example, often only the attribute and operation names are shown, and simple accessor methods are taken for granted. This results in a UML class that looks as follows (see Figure 3):
Figure 3 Attributes and methods with type, arguments, and modifier information omitted.
Now it's very easy to see the attributes and nontrivial operations of the class. However, it's still not very exciting. UML class diagrams start to come into their own when we have multiple classes and relationships between those classes on a diagram. UML represents relationships between classes by connecting the classes with a line. Different types of lines are used to indicate different types of relationships. The most common types of relationships shown on class diagrams are associations.
Associations
The attributes we have listed in our Person class so far have been of primitive types or simple objects that come as standard with Java. Consider the following snippet of Java code that adds a reference to an instance of an Organization class to our Person class.
public class Person { ... private Organization employer; ... }
The name of the reference suggests that the organization in question represents the employer of a person. Figure 4 shows how we represent the same thing in UML.
Figure 4 An association between two classes.
The line indicates that the class Person has a dependency on class Organization. The line is solid, which indicates that the type of dependency is an association.
An association can optionally show the roles, multiplicities, and direction of navigation, among other things. The association in Figure 4 shows that the Organization object plays an employer role in this relationship. The 0..1 indicates that each object of class Person knows of at most one object of class Organization, but may not know of any (that is, our reference could be set to null). The open-headed arrow indicates that the Person class has the reference to the Organization, not vice-versa.