Reading and drawing class diagrams
The notation interviewers expect, and what to leave out.
01The intuition
The problem it solves
Asked to design a hotel booking system, a candidate draws thirty boxes with every field and every getter, arrows in all directions, and runs out of time before writing a method. The interviewer wanted to see which classes exist, who owns whom, and where the rules live, in about three minutes of drawing. A class diagram is a tool for that conversation, and the obvious mistake is treating it as documentation of finished code.
# what the whiteboard looked like after ten minutes # Hotel: name, address, phone, stars, rooms, staff, get_name(), set_name(), ... # Room: number, floor, type, price, status, get_number(), set_number(), ... # Guest: id, name, email, phone, bookings, get_id(), ... # 30 boxes, 200 lines, zero behaviour, no method written yet
Build it one piece at a time
Step one: draw only the classes the use cases walked through, and inside each box write the two or three fields that carry state and the one or two methods that enforce a rule. Leave out getters, setters, ids and constructors; the interviewer assumes them.
# Hotel | rooms: list[Room] | find_free(type, dates) -> list[Room] # Room | number, type: RoomType | # Booking | room, guest, dates, status | cancel(), check_in() # Guest | name | # RoomType | STANDARD, SUITE (enum) |
Step two: draw the lines with the three shapes that interviewers expect and nothing else. A hollow triangle on the parent for inheritance, a filled diamond on the owner for composition (parts die with the whole), an open diamond for aggregation, a plain arrow for "uses or refers to". Put the multiplicity at each end as a number or an asterisk.
Step three: say the diagram out loud as you draw it, one sentence per line: "a hotel is made of rooms, so composition; a booking refers to one room and one guest; the room type is an enum because it is a fixed list with no behaviour yet." The sentences are the design; the boxes are notes for them.
from enum import Enum
from dataclasses import dataclass
class RoomType(Enum):
STANDARD = "standard"
SUITE = "suite"
@dataclass
class Room:
number: int
type: RoomType
class Hotel:
def __init__(self, rooms: list[Room]) -> None:
self._rooms = rooms # composition: the filled diamond
def find_free(self, type_: RoomType, dates: "DateRange") -> list[Room]:
return [r for r in self._rooms if r.type is type_ and not booked(r, dates)]
Why it works
The principle: a diagram is a shared picture for a decision you are about to make, so it should contain exactly the facts the decision needs. The invariant is that every line on the board maps to a field in the code and every box to a class, so the two never drift during the interview. Where it breaks: inheritance arrows drawn for every "is-a" the English allows (a suite is a room, so Suite extends Room, even though nothing differs but a price), arrows that cross because ownership was never decided, and diagrams with no methods at all, which tell the interviewer nothing about where the rules live. The test is simple: can you point at the box where "double booking is impossible" is enforced?
The trade-off you must say out loud
A diagram costs minutes you could spend on code, and some interviewers prefer boxes and arrows with no UML at all. Ask how much they want drawn. Draw the five classes the main use case needs, start coding, and add boxes only when a new requirement creates one. The follow-up is often a request to show one flow, which is a sequence diagram or simply a numbered list of calls, not a bigger class diagram.
Where it shows up in the 100 Google problems
- Hotel booking system: the example above, with the booking life cycle added as a state.
- Parking lot: the classic diagram interviewers expect: lot, floor, spot, vehicle hierarchy, ticket.
- Elevator controller: controller, car, door and request boxes with the dispatch strategy on a dashed line.
- Library management system: book versus copy and the loan link object drawn correctly.
- Splitwise: group composes expenses; a share is the link between an expense and a member.