Updated on 18 Jun, 202624 mins read 50 views

Why Relationships Matter

Suppose I give you these classes:

class User {}
class Order {}
class Product {}
class Payment {}

Do we have a design?

No

We only have isolated objects.

The real design begins when we answer:

How are these objects connected?

Relationships are the backbone of every software system.

Without relationships:

Objects are islands

With relationships:

Objects become a system

Think Like a Real World System

Imagine:

Customer places Order
Order contains Products
Payment pays for Order

This immediately creates a network.

Customer
    |
    |
    v
 Order
   |
   |
   v
Product

Order
   |
   |
   v
Payment

This network is called an:

Object Graph

Types of Relationships

There are five major types of relationships every designer must know:

1. Association
2. Aggregation
3. Composition
4. Dependency
5. Inheritance

Relationship 1 – Association

The simplest relationship.

Meaning:

Object A knows Object B

Example:

Teacher teaches Student

Teacher exists independently.

Student exists independently.

Suppose:

There are two classes Student and Course.

A student enrols in a course.

Question: Does Student own Couse?
No.

Question: Does Course own Student?
No.

They simply know about each other.
This is association.

Definition

Association is:

A relationship where one object knows about another object.

No ownership implied.

No lifecycle dependency implied.

Diagram:

Teacher ------ Student

Code:

class Student {}

class Teacher {
	students: Student[];
}

Teacher knows students.

Association.

class Course
{
};

class Student
{
private:
    Course* course;
};

Student knows about Course. Nothing more.

Characteristics:

Objects can exist independently.

Association implies:

Awareness
Communication
Collaboration

But NOT:

Ownership
Lifecycle Control

Example:

Teacher resigns

Students still exist.

Example:

Student leaves school

Teacher still exists.

Therefore:

Weak relationship

Real Examples

WhatsApp

User <--> Group

Food Delivery

Customer <--> Restaurant

Cardinality

Association usually has cardinality.

One-to-One

Person <--> Passport

One passport.

One person.

One-to-Many

Customer <--> Orders

One customer.

Many orders.

Many-to-Many

Student <--> Course

Many students.

Many courses.

Relationship 2 – Aggregation

Aggregation means:

Whole-Part Relationship

but

Part can exist independently.

Example:

Team --> Players

A team contains players.

But players can exist without team.

Definition

Aggregation is:

A whole-part relationship where parts can exist independently of the whole.

Diagram:

Team ◇──── Player

Empty White diamond

Code:

class Player {}

class Team {
   players: Player[];
}

If team is deleted:

Players survive.

Real World Example

Department

Department
     |
     +---- Employees

Delete department.

Employees still exist.

Lifecycle

Department destroyed:

Department dies

Employees:

Still alive

Aggregation Rule

Ask:

If parent dies,
does child survive?

If yes:

Aggregation

Relationship 3 – Composition

Composition is stronger.

Meaning:

Part cannot exist without whole.

Example:

House ---> Room

Room belongs to house.

Destroy house.

Room also disappears.

Definition

Composition is:

A strong ownership relationship where parts cannot exist independently.

Diagram:

House ◆──── Room

Filled Black diamond

Code:

class Room {}

class House {
    rooms: Room[];
}

Difference:

Aggregation:
			Parent removed
			Child survives
			
Composition:
			Parent removed
			Child removed

Real Example

Order

Order
   |
   +---- OrderItems

OrderItem has no meaning outside Order.

Composition.

Example:

class Order {
   items: OrderItem[];
}

Delete Order.

OrderItems disappear.

Aggregation vs Composition

Aggregation:

Department β†’ Employee

Team β†’ Player

Library β†’ Book

Child survives.

Composition:

Order β†’ OrderItem

House β†’ Room

Invoice β†’ InvoiceLine

Child dies with parent.

Comparison Table

AggregationComposition
Weak ownershipStrong ownership
Independent lifecycleShared lifecycle
Part survives ownerPart dies with owner
Empty diamondFilled diamond

Easy Memory Trick

Ask:

Can child live alone?

YES

Aggregation

NO

Composition

Relationship 4 – Dependency

Weakest relationship.

Meaning:

Object temporarily uses another object.

Example:

class PaymentService {
	process(order: Order) {}
}

PaymentService uses Order.

But doesn't own it.

Dependency.

Definition

Dependency is:

A relationship where one object temporarily relies on another.

Diagram:

PaymentService -----> Order

Characteristics:

Short-lived
Temporary
No ownership

Dependency means:

Uses
Needs
Calls

but not:

Contains
Owns

Real Example

class EmailService
{
public:
    void sendEmail()
    {
    }
};
class PaymentService
{
public:

    void processPayment(
        EmailService& email)
    {
        email.sendEmail();
    }
};

Temporary usage. No ownership.

Why Dependency Matters

Because dependency creates coupling.

Bad:

class UserService {
    private paymentService =
        new RazorpayService();
}

Strong dependency.

Good:

class UserService {
   constructor(
      paymentService:
      PaymentService
   ) {}
}

Dependency Injection.

Relationship 5 – Inheritance

Most abused relationship.

Meaning:

IS-A

Example:

Dog IS-A Animal

Code:

class Animal {}

class Dog extends Animal {}

Inheritance.

Diagram:

        Animal
           β–²
           |
      +----+----+
      |         |
     Dog       Cat

Valid Examples

Car IS-A Vehicle

Dog IS-A Animal

Admin IS-A User

Invalid Examples

Engine IS-A Card

No

Engine is part of car.

Composition.

Inheritance Test

Ask:

Can I replace β€œis a”?

Example:

Dog is an Animal

Valid.

Example:

Engine is a Car

Invalid.

No inheritance.

The Inheritance Trap

Beginners overuse inheritance.

Bad:

class Vehicle {}

class Car extends Vehicle {}

class ElectricCar extends Car {}

class Tesla extends ElectricCar {}

class ModelS extends Tesla {}

Deep inheritance tree.

Nightmare.

Modern design prefers:

Composition over Inheritance

Real Example:

Bad:

class Bird {
   fly()
}

Then:

class Penguin extends Bird {}

Problem:

Penguins cannot fly.

Inheritance broken.

This violates:

Liskov Substitution Principle

Relationship identification Framework

When modeling systems ask these questions:

Question 1:

Is-A?

If yes:

Inheritance

Question 2:

Whole-Part?

If yes:

Continue.

Question 3:

Can part exist independently?

If yes:

Aggregation

If no:

Composition

Question 4:

Does object simply know another?

If yes:

Association

Question 5

Does object merely use another?

If yes:

Dependency

Relationship Selection Framework

When modeling objects ask:

Question 1

Is it IS-A?

Yes

Inheritance

Question 2

Is it Part-Of?

Yes, then either Aggregation or Composition.

Ask:

Can child survive?

Yes

Aggregation

No

Composition

Question 3

Does object merely know another object?
Association

Question 4

Temporarily uses?
Dependency

Golden Rule of Professional LLD

When in doubt:

Prefer Composition

Over:

Inheritance

This single rule prevents many design disasters.

Relationship Strength Spectrum

Weakest
   |
   v

Dependency

Association

Aggregation

Composition

Inheritance*

   ^
   |
Strongest

(*Inheritance is conceptually different but often forms strong coupling.)

Buy Me A Coffee

Leave a comment

Your email address will not be published. Required fields are marked *