2.
How to Read a Class Diagram
Written by Joshua Greene
So now you know what design patterns are! In this chapter, you’re going to learn about a fundamental concept to help you understand design patterns: the class diagram.
Class diagrams are like engineering blueprints; they provide information about a system through the medium of pictures, symbols and annotations.
You may have heard of Unified Modeling Language (UML), which is a standard language for creating class diagrams, architectural drawings and other system illustrations. A complete discussion of UML is beyond the scope of this book, but you won’t need to understand a lot of UML in your day-to-day iOS development. Instead, you’ll learn a subset of UML in this chapter that’s useful for creating class diagrams and describing design patterns.
What’s in a class diagram?
Class diagrams include classes, protocols, properties, methods and relationships.
A box denotes a class. Here’s a very simple class diagram for a Dog
class:
To indicate that one class inherits from another, use an open arrowhead:
But instead of reading this as “inherits from,” read this as “is a”. For example, to show that SheepDog
inherits from Dog
, you’d draw the following diagram:
You would read this, from bottom to top, as “SheepDog is a Dog.”
Use a plain arrowhead to indicate a property, which is called an “association” in UML terms:
Class diagrams can be written from bottom to top, from left to right, or in any other orientation you’d like. Regardless of the orientation, the direction of the arrows define the meaning: Inheritance arrows always point at the superclass, and property arrows always point at the property class.
You should read a property arrow as “has a.” For example, if a Farmer
has a Dog,
you’d draw this:
You can indicate one-to-many relationships by specifying a range next to the arrowhead. For example, you can denote a Farmer
has one or more Dogs
like this:
You should always use the singular form of the class name in class diagrams, even if you’re conveying a one-to-many relationship. In this case, you should write Dog
, not Dogs
.
You can use as many arrows and boxes as you need in a single class diagram. For example, here’s how you’d denote a Farmer
has a SheepDog
that is a Dog
:
You also use a box to indicate a protocol. In order to distinguish it from a class, however, you need to write <<protocol>>
before its name.
Here’s how you’d denote a protocol called PetOwning
:
Use an open arrowhead with a dashed line to indicate a class implements a protocol:
You may either read this as “implements” or “conforms to.” For example, you’d indicate Farmer
conforms to PetOwning
like this:
Use a plain arrowhead with a dashed line to indicate “uses,” which is called a “dependency” in UML terms:
UML is intentionally vague about what a dependency is. Consequently, whenever you use a dependency arrow, you usually should annotate its purpose. For example, you can use a dependency arrow to indicate the following things:
- A weak property or delegate.
- An object that’s passed into a method as a parameter, but not held as a property.
- A loose coupling or callback, such as an
IBAction
from a view to a controller.
Here’s how you’d indicate that Dog
delegates to a PetOwning
object:
You can also denote properties and methods in a class diagram. For example, you’d indicate PetOwning
has a name
property and a petNeedsFood(_:)
method like this:
If an arrow’s meaning is obvious, you can omit any explanatory text. You can generally omit explanations for inheritance, properties and implements arrows. However, you should usually keep text for “uses” arrows, as their meaning isn’t always obvious.
Here’s the complete class diagram for a Farmer
that has a SheepDog
, which is a Dog
that delegates to a PetOwning
object:
Challenges
Now that you’ve got the basics down, it’s time to test your knowledge!
On a piece of paper, draw class diagrams for each of the following challenges. When you’re ready, check the next page for answers:
-
Dog
andCat
inherit fromAnimal
, which defines aneat
method. -
Vehicle
protocol has oneMotor
and one or moreWheel
objects. -
Professor
is aTeacher
and conforms to aPerson
protocol.
There are many correct solutions to each of these challenges. For example, you don’t have to draw the diagram from top to bottom. Instead, you can draw it from left to right or another orientation. As long as your class diagram clearly conveys the intended meaning, it’s correct!
Solutions on the next page.
Solution 1. You need three boxes: one for Cat
, Dog
and Animal
. You need an open arrowhead from Cat
to Animal
and another open arrowhead from Dog
to Animal
. You should also indicate eat()
on Animal
.
Solution 2. You should have three boxes: one for <<protocol>> Vehicle
, Motor
and Wheel
. You should have a plain arrowhead from Vehicle
to Motor
and another plain arrowhead from Vehicle
to Wheel
. You should also have 1 ... *
next to the arrowhead pointing at Wheel
.
Solution 3. The wording for this problem was intentionally ambiguous. We could have meant that either Teacher
conforms to Person
, or Professor
conforms to Person
. Thereby, Professor
would conform to Person
either directly or indirectly through Teacher
.
If Teacher
conforms to Person
and Professor
inherits from Teacher
, the class diagram looks like this:
If Professor
conforms to Person
, but Teacher
does not, the class diagram looks like this:
Key points
You learned the basics of class diagrams in this chapter. This is all you’ll need to understand the diagrams in the rest of this book. You can always refer back to this chapter if you need to do so!
-
Class diagrams give a visual representation of class and protocol types, showing their properties and methods.
-
Class diagrams also show the relationship between the object types.
-
Class diagrams can be drawn in any other orientation; the direction of the arrows define the meaning.
-
Boxes denote classes, and lines denote relationships: “implements,” “has a,” “uses“ and “conforms to” are the most common relations.
-
Boxes can also denote protocols, which is indicated by
<<protocol>>
before the name.