UML Diagrams
Class Diagram
Visualize the static structure, attributes, methods, and relationships of classes
UML Class Diagrams are the cornerstone of object-oriented design and Low-Level Design (LLD). They capture the static structure of a system by depicting its classes, attributes, methods, and the structural relationships among them. In software engineering, class diagrams serve as the bridge between abstract domain requirements and physical code implementation.
1. Learning Objectives
- Identify UML class diagram components: classes, interfaces, attributes, and methods.
- Decode UML symbols for accessibility (visibility) and structural relationships.
- Map class relationships—Association, Aggregation, Composition, Generalization, Realization, and Dependency—to code.
- Synthesize a comprehensive class diagram from raw textual business requirements.
- Implement type-safe, multi-class structures in Java, Python, and C++.
2. Problem Statement
Before writing a line of code, developers must align on how classes interact. Attempting to build a multi-class enterprise system—like a Library Management System or a Parking Lot—without a structural diagram leads to:
- Circular Dependencies: Classes referencing each other directly in ways that prevent compilation or create tight runtime coupling.
- Misaligned Lifecycle Ownerships: Deleting a
Libraryobject while leaving orphanBookobjects floating in memory, causing resource leaks. - Lack of Extensibility: Discovering halfway through implementation that adding a new member type requires changing multiple classes instead of simply inheriting from an abstraction.
3. Real-world Analogy
Think of a Residential Building Blueprint:
- The Analogy: A construction blueprint does not show how water actually flows through the pipes (that would be a sequence diagram) or how a door swing works. Instead, it specifies the room layouts, room sizes, the thickness of walls, and room connections (doorways, windows).
- The Mapping: In software, classes are the rooms, attributes are room dimensions/colors, methods are room functions (e.g., cooking in a kitchen), and doorways are the structural relationships that define how objects navigate between each other.
4. Theory (Diagram Components & Symbols)
A Class Diagram consists of Classes (depicted as boxes with three compartments) and Relationships (lines linking the boxes).
Class Box Compartments
- Top Compartment: The class name. Stereotypes like
«interface»or«abstract»are placed above the name if applicable. Abstract class names are italicized. - Middle Compartment: Attributes (fields/variables) listed with visibility markers, names, and types:
[visibility] name: type = [defaultValue]. - Bottom Compartment: Operations (methods/functions) listed with visibility, parameters, and return types:
[visibility] methodName(param1: type): returnType.
Visibility Symbols
+: Public (accessible everywhere)-: Private (accessible only within the declaring class)#: Protected (accessible within class and subclasses)~: Package-private / Default (accessible within package)
Relationship Symbols
| Relationship | Visual Line Symbol | Meaning |
|---|---|---|
| Generalization (Inheritance) | Solid line with hollow arrow (──▷) |
Subclass derives from parent class ("is-a"). |
| Realization (Implementation) | Dashed line with hollow arrow (- - ▷) |
Concrete class implements interface contract. |
| Composition | Solid line with filled diamond at parent (◆──) |
Strong ownership. Child's lifecycle bound to parent ("part-of"). |
| Aggregation | Solid line with hollow diamond at parent (◇──) |
Weak ownership. Child exists independently of parent ("has-a"). |
| Association | Solid line with simple arrow (──❯) |
Structural link between classes (e.g. holds reference). |
| Dependency | Dashed line with simple arrow (- - ❯) |
Temporary runtime relationship (e.g. local variable or parameter). |
5. Visual Diagrams (Library Management System)
Below is a comprehensive Class Diagram representing a Library Management System. It features composition (Library owns Books), aggregation (Book references Author), inheritance (User base class with Librarian and Patron), association (Patron borrows Book), and dependency (Patron uses SearchEngine):
6. Syntax Explanation
Standard UML notations translate to concrete class relationships:
- Composition (◆): Inside the parent constructor, instantiate the child class directly, or store them inside a private container and destroy them if the parent is deleted.
- Aggregation (◇): The parent class accepts the child references through constructor parameters or setters, indicating that they were created elsewhere.
- Generalization (▲): Implemented via class inheritance keywords:
extendsin Java, subclassing in Python, or public inheritance in C++. - Dependency (..❯): The dependent class is passed as a parameter to a method, rather than being stored as a class member variable.
7. Step-by-Step Creation
- Noun Extraction: Analyze the system requirements text. Underline all nouns (e.g. library, book, patron, author) to identify potential classes.
- Verb Extraction: Underline verbs (e.g. borrow, register, search) to identify potential class methods or operations.
- Visibility & Types: Assign visibility flags (+, -) and appropriate data types to attributes and operations.
- Establish Lifecycles: Determine class lifecycles to decide between Composition (e.g. if Library closes, Books inside are discarded) and Aggregation (e.g. if Book is deleted, the Author still exists).
- Define Multiplicity: Annotate associations with numbers representing how many instances participate (e.g., 1 Library has many Books).
8. Complete Code (Mini Project)
9. Code Walkthrough
Let's trace how key UML relationships map to the implementation code:
- Composition: The relationship between
LibraryandBookis modeled using exclusive ownership. In C++, this is enforced by storing books asstd::vector<std::unique_ptr<Book>>. If the library object is destroyed, the vector's smart pointers are cleaned up, automatically freeing the book allocations. - Aggregation: The relationship between
BookandAuthoris represented using shared pointers (e.g.std::shared_ptr<Author>in C++ or standard references in Java). If a book is deleted, the author object continues to exist independently in memory. - Association: The relationship between
PatronandBookis modeled by keeping reference pointers to books in the borrowed list. Patrons do not own the books, meaning the books' lifecycles are independent of the patron. - Dependency: The relationship between
PatronandSearchEngineis not stored as a class field. Instead,SearchEngineis passed as a parameter to thesearch()method, creating a temporary runtime dependency.
10. Execution Flow
- Initialization: A
Libraryobject is allocated on the heap. - Author Aggregation: An
Authoris instantiated. We then instantiate aLibrarian. - Book Registration (Composition): The librarian calls
registerBook(), invoking the library's internal book creation method. A newBookobject is instantiated on the heap, linking to the shared author, and added to the library's private book list. - Borrowing (Association): The patron calls
borrowBook(), updating the book's borrow state flag to true and adding the book's pointer to the patron's borrowed list.
11. Internal Working (References & Lifecycle)
At the compiler and memory model level, class relationships translate to pointer layouts:
- Java/Python Reference Management: Java and Python store all objects on the heap. Variables are pointers to these heap structures. The Garbage Collector (GC) counts reference paths. When a
Libraryobject is garbage collected, the references to itsbookslist are removed. If there are no other references (e.g. if the patron returned the books), the books are cleaned up as well. - C++ Smart Pointer Layout:
-
std::unique_ptr: Stores a single raw pointer on the heap and deallocates it when it goes out of scope. Perfect for Composition. -std::shared_ptr: Stores a raw pointer alongside a reference count control block. Aggregation uses shared pointers to allow multiple books to refer to the same author safely.
12. Complexity Analysis
- Time Complexity: $O(1)$ lookup for attributes and direct associations. Aggregated collections (such as scanning a list of books) require $O(M)$ time where $M$ is the collection size.
- Space Complexity: $O(K + E)$ memory footprint, where $K$ is the number of active objects and $E$ is the number of active associations (pointers stored in lists).
13. Best Practices
- Adhere to standard visibility guidelines: Keep class attributes private (
-) and expose them only via public methods (+) to maintain encapsulation. - Differentiate Aggregation and Composition: Use Composition (
◆) only when parent and child lifecycles are tightly coupled (e.g., Engine is part of Car). Use Aggregation (◇) for independent lifecycles (e.g., Professor is part of Department). - Specify Multiplicity: Always include multiplicity values (e.g.
1,0..*) to clarify association bounds.
14. Common Mistakes
- Using the wrong arrow head: Using a solid arrow for inheritance instead of a hollow triangle, or using a diamond at the child end rather than the parent end.
- Over-modeling boilerplate methods: Bloating diagrams by listing every getter and setter method. Focus on key business logic operations.
- Representing transient interactions as fields: Storing temporary parameters (like a search engine) as class fields instead of method arguments (dependency).
15. Interview Questions
Answer: Composition represents strong ownership (filled diamond) where child objects cannot exist without the parent (e.g. Room inside House). Aggregation represents weak ownership (hollow diamond) where child objects exist independently of the parent (e.g., Student inside Course).
Answer: By adding the stereotype
«interface» above the class name. The relationships implementing it are depicted with a dashed line and a hollow arrow pointing to the interface.
Answer: Use Dependency when class A interacts with class B temporarily (e.g., B is passed as a parameter to a method of A). Use Association when class A holds a persistent reference to class B as an instance attribute.
16. Practice Exercises
- Easy: Draw a class diagram representing a
Carcontaining anEngine(Composition) and a list ofPassengers (Aggregation). - Medium: Design a Class Diagram for a
ParkingLotcontaining multipleParkingFloors, which containParkingSlots of different sizes, supporting differentVehicletypes. - Hard: Design a Class Diagram for an E-Commerce system featuring
Customer,Guest,RegisteredCustomer,ShoppingCart,Order,Payment(CreditCard, PayPal), andProduct. Highlight proper inheritance and compositions.
17. Challenge Problem
Create a complete Class Diagram for a multi-room Hotel Reservation System. The system manages rooms (Single, Double, Suite), guests, reservations, bills, and hotel receptionists. Detail all access modifiers, attribute and method signatures, multiplicities, and relationships. Write the corresponding class layout in Java, Python, or C++ to show how guest billing interacts with room rates.
18. Summary
- UML Class Diagrams visualize the static design structure of a system.
- Access visibility is defined using the symbols
+(public),-(private), and#(protected). - Structural relationships include Association, Aggregation, Composition, Generalization, Realization, and Dependency.
- Composition defines strong ownership, whereas Aggregation defines weak, independent ownership.
19. Cheat Sheet
| UML Link | Arrow Notation | Code Translation | Ownership Level |
|---|---|---|---|
| Generalization | ──▷ (Hollow triangle) |
class Dog extends Animal |
Direct subclass connection |
| Composition | ◆── (Filled diamond) |
Instantiated in parent constructor | Strict ownership, bound lifecycles |
| Aggregation | ◇── (Hollow diamond) |
Passed as reference parameter/setter | Weak ownership, independent lifecycles |
| Association | ──❯ (Open arrow) |
Stored as instance attribute reference | Structural linkage only |
| Dependency | - - ❯ (Dashed open arrow) |
Passed as argument inside class method | Temporary runtime reference |
20. Quiz
1. Which compartment of the UML class box contains visibility, attributes, and types?
A) The top compartment
B) The middle compartment (Correct)
C) The bottom compartment
2. What does a plus sign (+) visibility symbol indicate?
A) Private
B) Protected
C) Public (Correct)
3. How is Composition distinguished from Aggregation in UML notation?
A) Composition uses a filled diamond; Aggregation uses a hollow diamond (Correct)
B) Composition uses a dashed arrow; Aggregation uses a solid arrow
C) Composition uses a hollow triangle; Aggregation uses a hollow diamond
4. What is the correct definition of Generalization?
A) A class implementing an interface
B) A subclass inheriting attributes and methods from a superclass (Correct)
C) A class calling another class as a local variable parameter
5. If class A uses class B only inside one method as a local variable, how is the relationship classified?
A) Composition
B) Association
C) Dependency (Correct)
6. What symbol is used to represent Protected visibility?
A) -
B) # (Correct)
C) ~
7. Under composition, what happens to child objects when the parent object is destroyed?
A) The child objects continue to exist in memory
B) The child objects are automatically destroyed along with the parent (Correct)
C) The child objects are moved to a global scope index
8. How is the implementation of an interface (Realization) represented visually?
A) Dashed line with a hollow arrow pointing to the interface (Correct)
B) Solid line with a filled diamond pointing to the interface
C) Dashed line with a solid arrow pointing to the interface
9. In C++, which smart pointer is most appropriate for modeling Composition?
A) std::shared_ptr
B) std::weak_ptr
C) std::unique_ptr (Correct)
10. What does the multiplicity indicator "0..*" mean?
A) Exactly zero instances
B) Zero or more instances (Correct)
C) Between zero and one instances
21. Next Lesson Preview
In the next lesson, we will cover the Use Case Diagram. We will explore how to model the relationships between actors and system requirements to map out user-facing boundaries!