Chapter 1 · Lesson 3

UML Class Diagrams — A Practical Primer

Every pattern in this course is drawn as a UML class diagram — learn the five arrows and the box notation and you can read any of them.

The class box

A class is a three-part box: name on top, attributes (fields) in the middle, operations (methods) at the bottom. Visibility markers prefix each member:

  • + public   - private   # protected   ~ package
  • Italic class names or methods mean abstract; underlined members mean static.
UML class box and its Java equivalent Account - balance: int - owner: String + deposit(amount: int) + getBalance(): int - audit(): void class Account { private int balance; private String owner; public void deposit(int a){} public int getBalance(){} private void audit(){} }
A UML class box and the Java class it describes — same information, two notations.

The relationships (the arrows)

Patterns are mostly about how classes relate, so the arrows matter more than the boxes. These six cover almost everything you'll see:

RelationshipNotationMeansJava
Inheritance (generalization)solid line, hollow triangle ▷"is a"class Dog extends Animal
Realizationdashed line, hollow triangle ◁┄"implements an interface"class Dog implements Pet
Associationsolid line →"knows / uses long-term"a field referencing another object
Aggregationhollow diamond ◇—"has a" (shared, can outlive)a Team holds Players passed in
Compositionfilled diamond ◆—"owns" (part dies with whole)a House creates its Rooms
Dependencydashed arrow ┄>"uses temporarily"a method parameter or local var

Reading it back as Java

Here's a small diagram described in code. A Car realizes Vehicle, is composed of an Engine, and depends on a Driver only inside one method:

interface Vehicle { void start(); }          // realization target

class Engine { void ignite() {} }

class Car implements Vehicle {               // ──▷ realization (dashed, hollow triangle)
    private final Engine engine = new Engine();  // ◆── composition: Car owns its Engine

    public void start() {
        engine.ignite();
    }

    void drive(Driver driver) {               // ┄> dependency: used only here, as a parameter
        driver.steer(this);
    }
}
Pro Tip

You rarely need a tool. A whiteboard sketch with boxes and the right arrow is enough to communicate a design. The arrow you'll draw most in patterns is realization — "this class implements that interface."

Common Mistakes
  • Confusing aggregation (parts can exist independently) with composition (parts die with the whole). When in doubt, ask "if I delete the whole, does the part still make sense?"
  • Drawing an association (a stored field) when you really mean a dependency (a passing parameter). Dependencies are weaker — prefer them.
Lesson Summary

A UML class box shows name, attributes, and operations with visibility markers (+ - #). Six relationships carry the design: inheritance and realization (is-a / implements), association/aggregation/composition (has-a, in increasing strength of ownership), and dependency (uses temporarily). Read the arrows first — that's where patterns live.