Limited time: AI code review, hints, mock interviews, whiteboard analysis, and all Pro features are unlocked. Enroll
⏱️ 7 min read

UML Class Diagrams

UML class diagrams show the static structure of a system: what classes exist, what they contain, and how they relate to each other. In interviews, you’ll sketch these during the first 5-10 minutes to plan your implementation.

Why this matters: A quick class diagram before coding helps you identify entities, relationships, and responsibilities. Interviewers also use them to evaluate your design. You don’t need full UML rigor – just enough to communicate structure clearly.


Prerequisites


Class Notation

A class box has three sections:

classDiagram
    class ParkingLot {
        -floors: List~Floor~
        -strategy: ParkingStrategy
        -billingService: BillingService
        +park(vehicle) Ticket
        +unpark(ticket) Receipt
        +getAvailableSlots(type) int
        -findSlot(vehicle) Slot
    }

Visibility modifiers:


Relationship Types

This is the core knowledge for interviews. Know these six:

classDiagram
    class Association
    class Aggregation
    class Composition
    class Inheritance
    class Implementation
    class Dependency

    Association --> Aggregation
    Aggregation o-- Composition
    Composition *-- Inheritance
    Inheritance <|-- Implementation
    Implementation <|.. Dependency

Quick Reference Table

Relationship Arrow Meaning Lifetime Example
Association --> A uses B Independent ParkingLot uses ParkingStrategy
Aggregation o-- A has B, B exists independently B survives A’s deletion Department has Employees
Composition *-- A owns B, B dies with A B cannot exist without A Order owns LineItems
Inheritance <\|-- B is-a A N/A Car extends Vehicle
Implementation <\|.. B implements A N/A TokenBucket implements RateLimitAlgorithm
Dependency ..> A temporarily uses B Momentary Service uses Logger in a method

Relationships in Practice

classDiagram
    class ParkingLot {
        -floors: List~Floor~
        -strategy: ParkingStrategy
    }
    class Floor {
        -slots: List~Slot~
        -floorNumber: int
    }
    class Slot {
        -slotId: String
        -type: SlotType
        -vehicle: Vehicle
        +isAvailable() bool
    }
    class Vehicle {
        -licensePlate: String
        -type: VehicleType
    }
    class ParkingStrategy {
        <<interface>>
        +findSlot(floors, type) Slot
    }
    class NearestFirstStrategy {
        +findSlot(floors, type) Slot
    }
    class Ticket {
        -vehicle: Vehicle
        -slot: Slot
        -entryTime: Instant
    }

    ParkingLot *-- Floor
    Floor *-- Slot
    Slot --> Vehicle
    ParkingLot --> ParkingStrategy
    ParkingStrategy <|.. NearestFirstStrategy
    ParkingLot ..> Ticket

Reading this diagram:


Multiplicity

Show how many objects participate in a relationship:

Notation Meaning
1 Exactly one
0..1 Zero or one (optional)
* or 0..* Zero or many
1..* One or many
3..5 Three to five
classDiagram
    class Order {
        -items: List~LineItem~
        -customer: Customer
    }
    class LineItem {
        -product: Product
        -quantity: int
    }
    class Customer {
        -orders: List~Order~
    }

    Customer "1" --> "*" Order
    Order "1" *-- "1..*" LineItem

Drawing Class Diagrams in Interviews (Speed Tips)

In a 90-minute round, you have about 5 minutes for a diagram. Focus on:

  1. Entities first – Just the class names in boxes. No methods yet.
  2. Key relationships – Composition and inheritance. Skip trivial associations.
  3. Interfaces where strategies exist – Show the Strategy or State interface with 2 implementations.
  4. Skip getters/setters – Only show meaningful methods.
  5. Use short names – ParkingStrategy not IParkingAllocationStrategyInterface.

Composition vs Aggregation: The Key Distinction

This confuses people. The question is: does the child survive if the parent is destroyed?

Composition (filled diamond) Aggregation (empty diamond)
Child dies with parent Child lives independently
Parent creates and owns child Parent references existing child
Order owns LineItems Team has Players
House owns Rooms Playlist has Songs
Implemented as: field created in constructor Implemented as: field passed in or set

In practice, most LLD designs use composition. Aggregation is rarer.


Common Mistakes

  1. Every relationship is a plain arrow – Distinguish between composition, inheritance, and dependency. They communicate different things.
  2. Too much detail – Don’t draw every field and every method. Focus on what communicates structure.
  3. Missing interfaces – If you have a Strategy or State pattern, the interface IS the relationship to show.
  4. Confusing direction – Arrows point FROM dependent TO dependency. ParkingLot --> ParkingStrategy means ParkingLot depends on ParkingStrategy.

When to Use vs When to Avoid

Draw a Class Diagram When Skip It When
5+ entities with non-obvious relationships System has 2-3 simple classes
Patterns like Strategy, State, Observer are involved It’s a straightforward CRUD system
Interviewer asks for it You’re running out of time – code first
You need to plan before coding Relationships are obvious from code

Interview Questions

  1. β€œWhat’s the difference between aggregation and composition?” – Composition: part dies with the whole (Order deletes its LineItems). Aggregation: part exists independently (Department doesn’t delete Employees when dissolved).

  2. β€œWhen do you use interfaces vs abstract classes?” – Interfaces for contracts that unrelated classes implement (Strategy). Abstract classes for shared implementation that related classes extend (Template Method).

  3. β€œShow me the class diagram for your solution.” – Be ready to draw one quickly. Focus on entities, key relationships, and patterns used. 5-6 boxes with arrows is ideal.


See It in Action

Every LLD problem on this site starts with a class diagram. See Parking Lot and File System for clear examples.


Translating Diagrams to Code

The mapping from UML to code is mechanical. Once you’ve drawn the diagram, the class skeletons write themselves.

// Composition (filled diamond): parent creates and owns child
public class Order {
    private final List<LineItem> items = new ArrayList<>(); // created internally
    
    public void addItem(Product product, int qty) {
        items.add(new LineItem(product, qty)); // Order creates LineItems
    }
}

// Association (plain arrow): references an external object
public class Slot {
    private Vehicle occupant; // assigned externally, not created here
    
    public void occupy(Vehicle v) { this.occupant = v; }
    public void free() { this.occupant = null; }
}

// Implementation (dashed arrow): implements an interface
public class NearestFirstStrategy implements ParkingStrategy {
    @Override
    public Slot findSlot(List<Floor> floors, VehicleType type) { /* ... */ }
}
# Composition: parent owns child lifecycle
class Order:
    def __init__(self):
        self._items: list[LineItem] = []  # created and owned by Order
    
    def add_item(self, product, qty):
        self._items.append(LineItem(product, qty))

# Association: references external object
class Slot:
    def __init__(self):
        self._occupant: Vehicle | None = None  # not owned
    
    def occupy(self, vehicle: Vehicle):
        self._occupant = vehicle

# Implementation: concrete class implements interface
class NearestFirstStrategy(ParkingStrategy):
    def find_slot(self, floors, vehicle_type):
        pass
// Composition: unique_ptr signals ownership
class Order {
    vector<unique_ptr<LineItem>> items_; // owned, dies with Order
public:
    void addItem(Product* product, int qty) {
        items_.push_back(make_unique<LineItem>(product, qty));
    }
};

// Association: raw pointer or reference (non-owning)
class Slot {
    Vehicle* occupant_ = nullptr; // not owned
public:
    void occupy(Vehicle* v) { occupant_ = v; }
    void free() { occupant_ = nullptr; }
};

// Implementation
class NearestFirstStrategy : public ParkingStrategy {
public:
    Slot* findSlot(vector<Floor>& floors, VehicleType type) override { /* ... */ }
};

Free system design + DSA prep. If it helped you crack an interview, consider supporting.

SensAI SensAI
Beta
Listening...
Tap mic to stop voice mode

Shape what we build next

Every piece of feedback is read by the team and directly influences our roadmap.

What type of feedback?

Install SystemCraft

Add to your home screen for instant access, offline reading, and a distraction-free experience.

Offline reading Faster loads No browser tabs App-like feel

Unlock AI Features

One click to activate - no payment, no credit card. Just sign in and you're in.

AI code review and hints
SensAI chat assistant
AI mock interviews
Whiteboard analysis
100% free during early access