Modeling with UML Class diagrams and relationships

Class diagrams and relationships

Read and draw the boxes and arrows that describe a system's structure.

  • 14 min read
  • 6 chapters
  • Lesson 2 of 3

What you will learn

  1. 01What a class diagram shows
  2. 02Associations and multiplicity
  3. 03Aggregation and composition
  4. 04Inheritance and interfaces
  5. 05Dependency
  6. 06From diagram to code
01

What a class diagram shows

A class diagram shows the static structure of a design: the classes, what each holds, what each can do, and how they relate. Each class is a box with three parts: its name, its attributes (data) and its operations (methods). A prefix marks visibility: + public, - private, # protected.

ParkingLot
- floors: Floor[]
+ enter(plate): Ticket
+ leave(id): number

Draw only what helps a reader. A diagram with every field of every class is unreadable and goes stale. Show the structure and the key operations.

owns 1..*has 1..*usescreatesParkingLotHLDenter, leaveFloorDBholds slotsSlotDBfree or takenPricingRuleREQinterfaceTicketCHECKentry time

Swipe sideways to pan · drag a box to move it

100%
A class: name, data and operations.
02

Associations and multiplicity

An association is a lasting link between two classes: a lot has floors, a ticket refers to a slot. A line connects them, and numbers at the ends give the multiplicity, how many instances take part.

  • 1 exactly one.
  • 0..1 zero or one.
  • 1..* one or more.
  • * any number.

A lot owns 1..* floors, and each floor holds 1..* slots. Multiplicity is design information. It tells the implementer whether to use a single field or a collection.

03

Aggregation and composition

Both mean has a, but they differ in who controls the life of the part.

  • Aggregation (hollow diamond) is a loose whole and part. The parts can exist without the whole, like a team and its players.
  • Composition (filled diamond) is strong ownership. When the whole is destroyed, so are its parts. A floor does not outlive its lot.
owns 1..*has 1..*usescreatesParkingLotHLDenter, leaveFloorDBholds slotsSlotDBfree or takenPricingRuleREQinterfaceTicketCHECKentry time

Swipe sideways to pan · drag a box to move it

100%
Composition and multiplicity: a lot owns one or more floors.

When unsure, use a plain association. Many teams never use aggregation at all.

04

Inheritance and interfaces

Generalization (a solid line with a hollow triangle) means is-a: a Truck is a Vehicle. Realization (a dashed line with a hollow triangle) means a class implements an interface: HourlyRule realizes PricingRule. Remember the earlier lesson: prefer composition, and use these arrows for genuine, stable relationships.

05

Dependency

A dependency (a dashed arrow) means one class uses another briefly, such as taking it as a parameter or calling it, without holding it as a field. It is the weakest link, and showing too many clutters the picture. Show a dependency only when it matters to the design.

owns 1..*has 1..*usescreatesParkingLotHLDenter, leaveFloorDBholds slotsSlotDBfree or takenPricingRuleREQinterfaceTicketCHECKentry time

Swipe sideways to pan · drag a box to move it

100%
A dependency on an interface keeps pricing replaceable.
06

From diagram to code

The mapping is mechanical, which is the point. A box becomes a class, an attribute becomes a field, an association with multiplicity 1..* becomes a list, a composition becomes a field the whole creates and owns, and a realization becomes implements.

class ParkingLot {
  private floors: Floor[] = [];
  constructor(private rule: PricingRule) {}
  enter(plate: string): Ticket { /* creates a Ticket */ }
}
owns 1..*has 1..*usescreatesParkingLotHLDenter, leaveFloorDBholds slotsSlotDBfree or takenPricingRuleREQinterfaceTicketCHECKentry time

Swipe sideways to pan · drag a box to move it

100%
The full structure that code will follow.

Use the diagram to find problems before coding: a class with a dozen arrows is too coupled, and a box with no behavior may be just data. Sketch, review, correct, then code.