Class Diagrams

Goals

Concepts

Language

Library

Preparation

Lesson

The hierarchy of classes you've designed produce a simplified representation of the world. The world is too complex to be fully reproduced in a Java program, and moreover many details of the real world are not relevant to solving particular problems. Classes and their relationships form an abstract model of the real world, allowing you to describe in Java code what data is relevant to a problem and what operations should be performed on that data to solve the problem.

But Java code is not always the best way to communicate your model to other people. The larger system you are implementing may contain components that are written in other languages. You may need to communicate with users, who may not know Java or may not even be programmers. Finally even if the person with whom you are communicating is a Java programmer, the saying still holds true that a picture is worth a thousand words. Humans can sometimes learn and understand a diagram quicker than reading computer code.

Class Diagrams

One of the fundamental diagrams of software development is the class diagram, a pictorial representation of a hierarchy of classes, their relationships, and their encapsulated data and functionality. Knowing how to draw and read class diagrams is important for communicating designs among team members and with users. Because class diagrams are themselves models, they may further simplify your classes in the interest of better communication.

Martin Fowler, a well-known expert on object-oriented analysis and design, has identified three ways that people use class diagrams and other models. The purpose of the model will determine the level of simplification versus the amount of rigor (the degree of accuracy down to minute details) used when creating class diagrams.

sketch
Class diagrams can help communicate a part of the system. The purpose is clarity, not completeness, and parts may be left out for simplification. In discussing sketches Martin Fowler says that comprehensiveness is the enemy of comprehensibility.
blueprint
Class diagrams can be used as a specification for others to use in implementing a system in program code. These class diagrams would need to be sufficiently complete so that a developer would have few doubts about how the data should be structured and what functionality should occur.
programming language
The modeling approach can be so complete that it functions as a language itself for writing programs. Tools exist that take class diagrams and other models and turn them into computer programs automatically.

UML

UML cube logo.
UML cube logo.

The Unified Modeling Language (UML) is undeniably the current standard approach for creating models of computer software. Produced by the Object Management Group (OMG), UML supports far more than class diagrams. UML allows models to expressed using two broad classes of diagrams:

As you can see from the above list, a class diagram is one of the structure diagrams, explaining how a program is put together. The behavior diagrams explain how a program functions and how its pieces interact.

Comments

UML comment.
A UML comment.

One of the most basic elements is a comment, which can be used in any of the UML diagrams. A comment often called a “note” because its symbol looks like the page of a “sticky note” with one corner bent. Comments allow you to clarify a diagram, or add details that may not be captured by UML. If the comment describes a specific part of the diagram, you may use a dashed line to connect the note to the item it relates to.

Stereotypes

UML «actor» stereotype for driver.
UML icon representation for the «actor» stereotype for the Driver class.

Although it has a comprehensive set of modeling elements already, UML itself to be extended to meet needs specific to each project. A common way to extend UML is to use a stereotype, which is a way of further classifying classes. You can use a stereotype to make a “special category of class”, by adding the name of the stereotype between double angle quotation marks « and », otherwise known as “guillemets”. UML also allows you to use a special icon to represent each stereotype.

For example a common UML stereotype is an actor, a role of a user or even another system that interacts with the program. It is possible to place the stereotype «actor» above the class name Driver to indicate a user who drives a car. It is probably more visually appealing, however, to use the common UML icon for «actor» which is shown as a stick figure drawing, as shown in the figure. Stereotypes appear in many UML diagrams, such as class diagrams and use case diagrams.

UML Class Diagrams

Creating class diagrams is the most popular use of UML. The built-in UML elements and stereotypes handle virtually all the features of Java classes and interfaces.

Classes

In UML a classifier, as UML calls all class-like thing, is generally represented by a simple rectangle with the name of the class inside, such as Car. To represent an instance of a class, such as one might get using new Car(), show the class name with an underline, such as Car. If appropriate you can also indicate a variable name before the instance, separated by a colon : character, such as myCar : Car.

UML classifiers.

Representation Diagram
Class Car UML class Car.
Class Instance myCar : Car UML class instance myCar.
Abstract Class AbstractVehicle UML abstract class AbstractVehicle.
Interface
«interface»
Vehicle
UML interface stereotype Vehicle.UML interface icon Vehicle.

The names of abstract classes are shown in italics, such as AbstractVehicle. To indicate an interface, you use the UML stereotype «interface» with a class, as UML thinks of an interface as merely a special type of class. (At the level of the JVM Java does much the same thing.) You can also use the special «interface» stereotype icon, which is simply a circle.

Relationships

Until now you've used the traditional object-oriented relationships of inheritance (between classes and between interfaces) and implementation (between a class and an interface). UML comes with ways to represent these types of relationships and more.

All relationships in UML are shown by some sort of line, either solid or dashed. You can clarify the relationship by writing things above and/or below the line—either in the middle of the line, to describe the relationship itself, or next to one of the classes, to give more detail on the part that class plays in the relationship.

Multiplicity

While one class may be related to another other in a class diagram, at runtime there may be many instances of the identified classes taking part in the relation. It's often useful to define multiplicity: how many instances will take part in each side of a relationship. To specify multiplicity UML allows a single number such as 5, or the asterisk * character which indicates “unlimited”.

Driver drives Car
A Driver may drive many Cars.

For example, a Car may be related to a Driver actor; a Driver may drive many Cars, but each of the Car instances can only have a single Driver. The Driver side of the relationship would therefore display 1, while the Car side of the relationship would display *, as shown in the figure.

UML also allows a range of number using two stop or period . characters. A multiplicity of “zero, one, two, or three” would be in indicated as 0..3. “One or more” would be indicated as 1..*. In fact any multiplicity can be presented in the “long” range form; a multiplicity of 1 could also be presented as 1..1, for example.

Relationship Types

There are six main types of relationships in UML. If a relationship has navigability, it means the relationship goes only in one direction, from one class to another. Navigability is indicated by some sort of arrow or a diamond on one end of the line. For example implementing an interface is a navigable relationship; the pointing arrow indicates that the class implements the interface and not the other way around.

Generalization
Vehicle hierarchy class diagram.
Class diagram using generalization to indicate inheritance.

UML refers to an inheritance relationship as generalization. You might have expected this relationship to be called “specialization” because a subclass is a more specialized type than its super class. This name reflects its representation in a UML diagram: a line with a triangle-shaped arrowhead is used to point to the more general class in the relationship. You saw generalization in use in the first class on inheritance, in which a Vehicle is more general than a Car, and a Car is more general than a SportsCar.

Realization

UML uses the term realization to refer to interfaces. UML was meant to be a general modeling language with many applications, so while Java would say that a class “implements” some interface, UML would say that the class “realizes” that interface, which is a more general way of saying the same thing. The diagram representation of realization is the same as for generalization, except that a dashed line is used instead of a solid line. The triangle arrowhead points to the interface being realized/implemented.

StringBuilder realizes Appendable.
StringBuilder realizes (implements) interface Appendable.

The diagram above shows how the class java.lang.StringBuilder, which you studied when learning about unit tests, implements the interface java.lang.Appendable. As you saw in the lesson on interfaces, the Appendable interface represents a generalized way to “append” sequences of characters to some object.

Association

Two classes can be related in a more general way, other than inheritance. A car may have a manufacturer, for example. UML relates such general association by a single, solid line.

Company manufacturers Vehicle.
Company is associated with a Vehicle as its manufacturer.

When two classes are associated, an instance of each of the classes usually has a reference to an instance of the other. If only one of the classes has a reference to the other, the relationship is only navigable in one direction; this would be indicated with an open arrowhead on one end of the line, indicating the direction of navigability. UML allows various types of navigability, and even provides a way to indicate that the relationship is not navigable.

Dependency

An even weaker relationship between two classes is a dependency that one class has on another. A Car usually needs to refill its fuel at a GasStation, for example. UML uses the same notation in component diagrams to denote a dependency between a program and a library such as Google Guava.

Car uses GasStation.
Car has a dependency on GasStation.
Aggregation

A stronger relationship than association is one of aggregation, in which instances of one class actually own instances of another class. In an aggregation the class that is owned may still be shared with other classes. A car rental agency likely owns a whole fleet of cars, for example, yet the cars are still separate entities. The agency rents the cars to other drivers or companies, even though the cars are still owned by the rental agency. In this example “owns” is used in the legal sense, but it is analogous to the concept of one class controlling and being responsible for another class.

CarRentalAgency owns Car.
CarRentalAgency aggregates one or more Cars.
Composition

An even stronger relationship than aggregation is composition, in which one class actually “contains” another. Composition is often described as a “whole-part” relationship, because one of the classes may not normally exist except as part of the other class. The engine of a car is a good example; normally you wouldn't expect to create an instance of Engine by itself. Instead you would create a Car instance, and the Car class would completely contain the Engine as one of its parts.

Engine is part of Car.
A Car is composed of an Engine; an Engine is a part of a Car.

Features

As you already know from programming Java, a class is more than just a “box” with with a name: it encapsulates data and functionality. UML allows you to indicate such class features in optional, separate, divided sections in the class rectangle under its name. The first section holds properties, while the second holds operations. If operations are provided with no properties, an empty properties section must be included so that properties and operations will not be confused.

Point class with features.
Point class with features.

Properties

UML properties cover the data-encapsulation aspect of classes, including Java class instance and static variables. Properties were called attributes in earlier versions of UML. Each property has a name; its type, which is optional, appears after a colon : character. Static properties are shown underlined, such as ORIGIN.

Here are the properties that are part of the Point class in the figure.

UML allows one or more property modifiers to be listed, separated by commas, inside brace characters { } after the property. Here are some common property modifiers:

id
The property represents the identifier for the class.
ordered
The property values come in some order in the class instances.
readOnly
The property's value cannot be modified. This is implemented with the final keyword in Java.
unique
Each distinct class instance has a unique value for the property.

For example property modifiers of {id, unique, readOnly} would indicate that each class instance would have a unique value for the property, serving as its identifier, and the value could not be changed.

Operations

UML operations are used to represent Java methods. Each operation has a name, and like Java parameters are listed inside parentheses. Each parameter appears similar to a property, with its name followed by an optional type and separated by the colon : character. Even the method's return type (which is optional for void) is listed after the method itself, rather than before the method as in Java. Static operations, like static properties, are shown underlined, such as slope(point1 : Point, point2 : Point) : double. Abstract operations, like abstract classes, are shown in italics, such as update().

Here are the operations that are part of the Point class in the figure.

Visibility

UML provides equivalents of all the different visibility levels available in Java. If you wish to indicate visibility, place one of the symbols below before each property and operation to indicate which other classes can see the corresponding feature. A visibility indicator is optional, depending on the purpose of the diagram.

Visibility symbols
Symbol Visibility
+ public
- private
# protected
~ package

Here are some examples of visibility specifiers from the Point class in the figure above.

Multiplicity

Rectangle class with property multiplicity.
Rectangle class with property multiplicity.

If a property has more than one value (such as might be implemented by a Java array), UML allows the multiplicity to be indicated after the property type or, if no type is indicated, after the property name. For example a Rectangle class might contain four points representing the four corners of the rectangle. It might also indicate an optional background color:

Domain-Driven Design

To create an appropriate class hierarchy, you need to understand the subject area your program addresses, or its domain. Effectively implementing a solution requires developing a conceptual view of the domain—a domain model—and letting this model drive the design of your classes and interface.

But modeling the domain is not enough; developers, users, manager, marketing representatives, and others all need to be able to communicate with each other using the same terms and concepts, or what Eric Evans calls an “ubiquitous language”. UML class diagrams are an excellent tool for helping to communicate this shared view of the system. UML class diagrams used to express domain models will not be as detailed as the “blueprints” you may use to specify classes and interfaces for other developers. Rather than included detailed information about variable visibility and accessor methods, these “sketches” may simply use properties to indicate the attributes of an entity, for example.

Domain model diagram of item and suppliers.
Class diagram used as a sketch to illustrate a domain model of items and suppliers.

Recall the store owner with the furniture and toys; and related suppliers in the lesson on indirection. Before you can effectively create classes and interface to represent the entities, and before you can design a database in which to store the information, you must be able to communicate with the store owner about his/her needs. The UML class diagram in the figure illustrates how a sketch can help develop an “ubiquitous language” use throughout development for understanding and describing the domain.

Review

Summary

Classifiers

Representation Diagram
Class Car UML class Car.
Class Instance myCar : Car UML class instance myCar.
Abstract Class AbstractVehicle UML abstract class AbstractVehicle.
Interface
«interface»
Vehicle
UML interface stereotype Vehicle.UML interface icon Vehicle.
Relationships
Relationship Diagram
Dependency UML dependency relationship line.
Association UML association relationship line.
Aggregation UML aggregation relationship line.
Composition UML composition relationship line.
Realization (Implementation) UML realization relationship line.
Generalization (Inheritance) UML generalization relationship line.
Visibility
Visibility Symbol
public +
private -
protected #
package ~
Multiplicity
Long Form Short Form Meaning
0..0 0 none
0..1
optional
1..1 1 exactly one
0..*
*
zero or more
1..*
one or more

Gotchas

In the Real World

Think About It

Self Evaluation

Task

Create two UML class diagrams:

  1. A sketch of the publication domain model.
  2. A blueprint of the classes and interfaces Booker uses to implement the domain model.

See Also

References

Resources

Acknowledgments