How to Draw a UML Class Diagram
The controversy around class diagrams is that they get treated as deliverables rather than thinking tools. The genuinely useful version is quick: sketch which objects exist, who holds whom, and who depends on what, discuss it, and move on — no maintenance burden required.
First decide whether to draw one
Class diagrams suit complex object models, multi-person collaboration, and cross-language or cross-team alignment. They do not suit requirements still in flux, small features where the code speaks for itself, or teams that already use code review as their design document. A diagram nobody reads costs more than no diagram.
- Worth drawing: domain models, shared library interfaces, long-lived core modules
- Not worth drawing: throwaway scripts, plain CRUD endpoints, actively shifting requirements
- Draw on demand: only the contested slice, never the whole system
Three compartments: name, attributes, operations
The standard form is a rectangle split into three: class name on top, attributes in the middle, operations at the bottom. During design discussion the name and key attributes usually suffice; operations can be omitted because method signatures stabilise late and early guesses just cause rework.
- Use singular nouns for class names, matching the type names in code
- Mark visibility: plus for public, minus for private, hash for protected
- Write attributes as name colon type — do not drop the type
- Italicise or tag abstract classes and label interfaces separately; they are not the same thing
Tell the six relationships apart
Relationships are the hard part. Ordered by coupling strength: inheritance, realisation, composition, aggregation, association, dependency. The distinctions are not academic — the difference between composition and aggregation determines whether one object dies with another.
- Inheritance (solid line, hollow triangle): the child is a kind of the parent
- Realisation (dashed line, hollow triangle): the class implements an interface
- Composition (solid line, filled diamond): strong ownership, parts die with the whole
- Aggregation (solid line, hollow diamond): weak ownership, parts outlive the whole
- Association (plain or directed line): a long-lived reference; the default choice
- Dependency (dashed arrow): temporary use, such as a method parameter
Always mark multiplicity
The numbers at each end of a relationship (1, 0..1, star, 1..star) say how many of the other object are held. That is not documentation trivia: 1 usually means a single field, star means a collection, and 0..1 implies nullability. Leave it blank and every implementer will guess differently.
- Write 1, 0..1, star, or 1..star explicitly — never leave it empty
- For one-to-many, put the star on the many end
- Use bidirectional associations sparingly; a unidirectional one plus a query method is usually better
- Role names at each end remove a lot of explanatory text
Layout and scale control
A class diagram becomes unreadable past a dozen or so classes. Split by responsibility, draw one package or one core chain per diagram, and substitute package names for the rest. Lay inheritance vertically and associations horizontally and crossings drop noticeably.
- Keep each diagram to ten or fifteen classes; split by package beyond that
- Inheritance trees run vertically, parents above children and aligned
- Place heavily related classes near each other to shorten connectors
- Use colour to mark layers or modules, one colour family per module
Frequently asked questions
- Must a class diagram show operations?
- During design discussion, usually not. Method signatures change frequently during implementation, and drawing them early invites rework. Add key operations later, once the interface is settled and the diagram serves as a contract.
- How do I decide between composition and aggregation?
- Look at whether lifecycles are bound. If the part must be destroyed with the whole, use composition (filled diamond); if the part can exist independently or be referenced elsewhere, use aggregation (hollow diamond). When unsure, start with a plain association and refine later.
- How is a class diagram different from an ER diagram?
- A class diagram describes objects with behaviour, oriented toward code structure, and may include operations. An ER diagram describes data entities and their cardinality, oriented toward storage, with fields only. The two usually map onto each other for a given system, but they answer different questions.
- Are class diagrams needed in agile development?
- Not comprehensively, but they earn their place as sketches at key design points. A common practice is ten minutes at the whiteboard, a photo once the discussion settles, and no formal document to maintain. The point is thinking, not artefacts.