UML: Class & Object Diagrams

Aggregation & Composition

18 min Lesson 4 of 10

Aggregation & Composition

Most objects in a real system do not exist in isolation — they are made of smaller parts, and those parts can themselves have sub-parts. UML captures these whole-part relationships with two closely related notations: aggregation and composition. Both are drawn as a line with a diamond on the "whole" end, but the diamond shape carries a crucial difference in meaning that directly shapes how you design your database, your code, and your business rules.

Understanding the distinction is one of the most practical skills an analyst can develop: it determines whether deleting a parent record should cascade to children, whether parts can be shared across multiple parents, and how tightly or loosely components are coupled.

The Shared Diamond Metaphor

Both aggregation and composition use a diamond on the "whole" (parent) end of the relationship line. The diamond visually communicates that one class contains, is made of, or manages a collection of another class. The key difference lies in lifecycle dependency and exclusivity:

  • Aggregation (hollow diamond ◇): a "has-a" relationship where the part can exist independently of the whole. If the whole is destroyed, the parts survive. Parts may even be shared across multiple wholes.
  • Composition (filled diamond ◆): a "consists-of" relationship where the part cannot exist independently. If the whole is destroyed, all its parts are destroyed with it. A part belongs to exactly one whole at any moment.
Analyst rule of thumb: Ask two questions about the part. First — "Can this part exist without its parent?" Second — "Can this part belong to more than one parent at the same time?" If the answer to either is YES, use aggregation (hollow). If both answers are NO (it cannot exist alone and belongs to one parent only), use composition (filled).

Diagram 1 — Notation Side by Side

The diagram below shows both notations with labeled call-outs so you can commit the shapes to memory before applying them to a real scenario.

Aggregation vs Composition Notation Department - name (operations) Employee - empId (operations) 1 * Hollow ◇ = Aggregation Aggregation lifecycle: Employee exists independently; can move to another Department Order - orderId (operations) OrderLine - qty (operations) 1 1..* Filled ◆ = Composition Composition lifecycle: OrderLine is deleted when its Order is deleted
Side-by-side comparison: hollow diamond (aggregation) between Department and Employee vs filled diamond (composition) between Order and OrderLine.

Aggregation in Depth: The Department — Employee Example

An online store has departments (Marketing, Engineering, Logistics) and employees who belong to a department. This is a classic aggregation scenario:

  • An Employee has an independent existence: before being assigned to any department, they exist in the HR system. After leaving a department, they might move to another department — or the company might restructure and eliminate a department while retaining its employees.
  • Deleting the Marketing Department record does not delete the Employee records; those employees are reassigned or their department foreign key is set to null.
  • In some organizations an employee can even be assigned to multiple departments (shared-part aggregation). UML allows this in aggregation but not in composition.

The notation places the hollow diamond on the Department end (the whole) with multiplicity 1, and on the Employee end (the part) with multiplicity * (zero or more employees per department).

Database implication: Aggregation typically maps to a nullable foreign key on the part table. employees.department_id allows NULL so an employee can exist without a department, and ON DELETE SET NULL (or no cascade at all) is the safe default.

Composition in Depth: The Order — OrderLine Example

In the same online store, a customer places an Order and each order contains one or more OrderLine items (each line captures a product, quantity, and unit price). This is a composition relationship because:

  • An OrderLine has no meaning outside its parent Order. "Quantity: 2, Price: 49.99" means nothing if you do not know which order it belongs to.
  • When an order is permanently deleted (e.g., a cancelled order purge), every associated OrderLine is deleted with it — the business rules require it and the data model enforces it.
  • An OrderLine can never simultaneously belong to two different orders.

The filled diamond sits on the Order end with multiplicity 1. The OrderLine end carries multiplicity 1..* (every order must have at least one line).

Database implication: Composition maps to a non-nullable foreign key with cascade delete. order_lines.order_id NOT NULL plus ON DELETE CASCADE enforces that lines are destroyed with their parent order.

Diagram 2 — Library System: Both Relationships Together

A library system provides a richer example that uses both relationships in the same diagram, which is the norm in real class models.

  • A Library has many Book records — but books can be transferred to a branch library or sold off; they exist independently of any particular library. Aggregation.
  • A Book is composed of Chapter objects — a chapter has no identity or meaning outside its book; deleting the book record destroys all its chapters. Composition.
  • A Loan record is composed of LoanItem entries (one per book borrowed in a multi-book loan) — the loan items cannot outlive the parent loan record. Composition.
Library System — Aggregation and Composition Library - libraryId + searchBooks() Book - isbn - title + getDetails() 1 * aggregation Chapter - chapterNo + getContent() 1 1..* composition Loan - loanDate + close() LoanItem - dueDate + renew() 1 1..* composition Legend Aggregation Composition
Library system class diagram showing aggregation (Library — Book, hollow diamond) and composition (Book — Chapter, Loan — LoanItem, filled diamond) with multiplicity labels.

Reading the Library Diagram

Walk through each relationship and verify the two lifecycle questions:

  1. Library ◇ — * Book (aggregation): A book can exist in a catalogue independently of any branch library. When a library branch closes, its books are transferred, not destroyed. Independent existence? Yes. Shared? Possibly. Result: aggregation.
  2. Book ◆ — 1..* Chapter (composition): A chapter (e.g., "Chapter 3") has no identity or purpose without its book. If the book record is deleted, all chapter records are deleted too. Independent existence? No. Belongs to one book only? Yes. Result: composition.
  3. Loan ◆ — 1..* LoanItem (composition): A loan item (a specific book on a specific loan) has no meaning outside its parent loan transaction. Closing and deleting a loan record should cascade to all its items. Result: composition.

A Practical Decision Checklist

When you encounter a potential whole-part relationship during requirements analysis, run through these four questions in order:

  1. Is this genuinely a whole-part relationship? If two classes simply know about each other (e.g., Customer places Order), that is a plain association, not aggregation or composition.
  2. Can the part exist without the whole? If YES — aggregation. If NO — consider composition.
  3. Can the part belong to more than one whole simultaneously? If YES — aggregation (shared). If NO — lean toward composition.
  4. When the whole is destroyed, should the part be destroyed too? If YES — composition. If NO — aggregation.

Common Analyst Mistakes

Overusing composition: A frequent error is using the filled diamond for every "has-a" relationship. Always ask whether the part survives its parent. A Company has Employee objects — but employees are not composed inside a company; they exist independently and can leave. Use aggregation.
Confusing composition with inheritance: Composition is a whole-part relationship ("an Order has OrderLines"); inheritance is a classification relationship ("a SavingsAccount is a BankAccount"). These are completely different arrows in UML. Never use a filled diamond to show that one class is a specialization of another.

Summary

  • Aggregation (hollow diamond ◇) — the part can exist independently and may be shared. Lifecycle is independent. Database: nullable FK, no cascade delete.
  • Composition (filled diamond ◆) — the part cannot exist without its whole and belongs to exactly one whole. Lifecycle is coupled. Database: non-nullable FK with cascade delete.
  • The diamond always sits on the whole (parent) end of the line.
  • Multiplicity labels still apply: the whole end typically carries 1 or 0..1; the part end carries *, 1..*, or a fixed number.
  • Asking two lifecycle questions — "Can the part exist alone?" and "Can it belong to more than one whole?" — reliably guides the choice between the two notations.