Bird
Raised Fist0
LLDsystem_design~7 mins

Relationships (association, aggregation, composition) in LLD - System Design Guide

Choose your learning style10 modes available
Problem Statement
When designing software, unclear or incorrect relationships between objects cause tight coupling, memory leaks, or unexpected object lifetimes. This leads to bugs where objects are deleted too early or remain in memory unnecessarily, making the system fragile and hard to maintain.
Solution
Use clear relationship types to define how objects connect and depend on each other. Association means objects know each other but manage their own lifetimes. Aggregation means one object contains others but they can exist independently. Composition means one object owns others and controls their lifetimes, deleting them when it is deleted.
Architecture
Object A
(Association)
→Object B
↓
Object D
(Aggregation)
↓
↓
Object G
(Composition)
→Object H

The diagram shows three types of relationships: association where objects reference each other loosely, aggregation where one object contains others but they can live independently, and composition where one object owns and controls the lifetime of contained objects.

Trade-offs
✓ Pros
→
Association allows flexible connections without ownership, reducing tight coupling.
→
Aggregation models whole-part relationships without forcing lifetime dependency.
→
Composition ensures contained objects are cleaned up automatically with the owner, preventing memory leaks.
✗ Cons
→
Association can lead to dangling references if not managed carefully.
→
Aggregation requires careful lifetime management to avoid orphaned objects.
→
Composition can cause tight coupling and less reuse since contained objects depend fully on the owner.
Use association when objects interact but manage their own lifetimes. Use aggregation when parts can exist independently but belong to a whole. Use composition when parts must be created and destroyed with the whole, ensuring strict ownership.
Avoid composition if parts need to be shared or reused independently. Avoid aggregation if lifetime management is unclear or complex. Avoid association if ownership and lifecycle need to be strictly controlled.
Real World Examples
Amazon
Uses composition in their order system where an Order object owns OrderItems, ensuring items are deleted when the order is canceled.
Uber
Uses aggregation between Drivers and Vehicles, as vehicles can exist independently of drivers and be reassigned.
LinkedIn
Uses association between User profiles and Groups, where users can join or leave groups without ownership.
Code Example
The before code shows a Car tightly coupled to an Engine it creates internally, making reuse and testing harder. The after code shows association where Vehicle references a Driver without owning it, aggregation where Team contains members that can exist independently, and composition where House creates and owns Room objects, controlling their lifetime.
LLD
### Before: No clear relationship, tight coupling and unclear ownership
class Engine:
    def __init__(self):
        self.status = 'off'

class Car:
    def __init__(self):
        self.engine = Engine()  # tightly coupled

car = Car()
print(car.engine.status)


### After: Clear relationships
# Association example
class Driver:
    def __init__(self, name):
        self.name = name

class Vehicle:
    def __init__(self):
        self.driver = None  # association: vehicle knows driver but does not own

vehicle = Vehicle()
driver = Driver('Alice')
vehicle.driver = driver

# Aggregation example
class Team:
    def __init__(self):
        self.members = []  # aggregation: members can exist independently

    def add_member(self, member):
        self.members.append(member)

team = Team()
member1 = Driver('Bob')
team.add_member(member1)

# Composition example
class Room:
    def __init__(self):
        self.lights_on = False

class House:
    def __init__(self):
        self.rooms = [Room() for _ in range(3)]  # composition: house owns rooms

house = House()
print(len(house.rooms))
OutputSuccess
Alternatives
Dependency Injection
Instead of owning or containing objects, dependencies are passed in from outside, reducing tight coupling.
Use when: When you want to increase testability and flexibility by decoupling object creation from usage.
Event-driven communication
Objects communicate via events rather than direct references, reducing direct dependencies.
Use when: When you want loose coupling and asynchronous interactions between components.
Summary
Clear object relationships prevent bugs related to ownership and lifetime management.
Association, aggregation, and composition differ by how strongly objects are connected and who controls their lifetimes.
Choosing the right relationship type improves code clarity, reuse, and resource management.

Practice

(1/5)
1. Which relationship describes two objects connected without ownership, where both can exist independently?
easy
A. Inheritance
B. Association
C. Composition
D. Aggregation

Solution

  1. Step 1: Understand relationship types

    Association means objects are linked but do not own each other and can exist separately.
  2. Step 2: Compare with other relationships

    Aggregation and composition imply ownership; inheritance is a different concept.
  3. Final Answer:

    Association -> Option B
  4. Quick Check:

    Association = connected without ownership [OK]
Hint: No ownership means association, not aggregation or composition [OK]
Common Mistakes:
  • Confusing aggregation with association
  • Thinking composition allows independent existence
  • Mixing inheritance with relationships
2. Which of the following correctly shows a composition relationship in UML notation?
easy
A. A solid diamond at the owner end connected to the part
B. A hollow diamond at the owner end connected to the part
C. A plain line with no diamonds between objects
D. A dashed arrow pointing from part to owner

Solution

  1. Step 1: Recall UML notation for composition

    Composition uses a solid diamond at the owner end to show strong ownership.
  2. Step 2: Differentiate from aggregation and association

    Aggregation uses hollow diamond; association uses plain line; dashed arrow is for dependency.
  3. Final Answer:

    A solid diamond at the owner end connected to the part -> Option A
  4. Quick Check:

    Composition = solid diamond [OK]
Hint: Solid diamond means composition, hollow means aggregation [OK]
Common Mistakes:
  • Mixing hollow and solid diamonds
  • Confusing association line with composition
  • Using dashed arrows for composition
3. Consider this code snippet representing relationships:
class Engine:
    pass

class Car:
    def __init__(self):
        self.engine = Engine()
What type of relationship does Car have with Engine?
medium
A. Association
B. Aggregation
C. Inheritance
D. Composition

Solution

  1. Step 1: Analyze ownership in code

    Car creates and owns Engine instance inside its constructor, implying strong ownership.
  2. Step 2: Match with relationship definitions

    Since Engine cannot exist meaningfully without Car here, this is composition.
  3. Final Answer:

    Composition -> Option D
  4. Quick Check:

    Car owns Engine fully = Composition [OK]
Hint: Creating owned object inside means composition [OK]
Common Mistakes:
  • Thinking it's aggregation because of ownership
  • Confusing association with composition
  • Assuming inheritance from code
4. Identify the error in this aggregation example:
class Wheel:
    pass

class Car:
    def __init__(self, wheels):
        self.wheels = wheels

car = Car([Wheel(), Wheel()])
What is wrong with this aggregation?
medium
A. Wheels cannot exist independently in aggregation
B. Car should not hold wheels as a list
C. No error; this is correct aggregation
D. Wheels should be created inside Car for composition

Solution

  1. Step 1: Understand aggregation ownership

    Aggregation means Car owns wheels but wheels can exist independently.
  2. Step 2: Check code for ownership and independence

    Wheels are created outside Car and passed in, so they can exist alone, matching aggregation.
  3. Final Answer:

    No error; this is correct aggregation -> Option C
  4. Quick Check:

    Aggregation allows independent parts [OK]
Hint: Aggregation parts created outside owner, passed in [OK]
Common Mistakes:
  • Thinking wheels must be created inside Car
  • Confusing aggregation with composition
  • Assuming list usage is wrong
5. You are designing a library system where a Library contains many Books. Books can exist outside the library and be moved between libraries. Which relationship best fits this scenario and why?
hard
A. Aggregation, because library owns books but books can exist alone
B. Composition, because books depend fully on the library
C. Association, because library and books are loosely connected
D. Inheritance, because books inherit properties from library

Solution

  1. Step 1: Analyze ownership and existence

    Books can exist independently and move between libraries, so they are not fully owned.
  2. Step 2: Match relationship type

    Aggregation fits because library owns books but books can exist alone and be shared.
  3. Final Answer:

    Aggregation, because library owns books but books can exist alone -> Option A
  4. Quick Check:

    Aggregation = ownership with independent parts [OK]
Hint: If parts can exist alone, use aggregation [OK]
Common Mistakes:
  • Choosing composition thinking books depend fully
  • Selecting association ignoring ownership
  • Confusing inheritance with ownership
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard