System Design - 1

 

📘 System Design

System Design is the process of planning and defining the architecture, components, modules, interfaces, and data flow of a system so that it meets the required functionality, performance, scalability, and reliability.

In simple terms, system design explains how a software system should be structured and how its parts interact to solve a problem.


1️⃣ Definition

System Design is the high-level and low-level design of a software system that transforms requirements into a structured solution.

It defines:

  • How different components interact

  • How data flows through the system

  • How the system handles scale, failures, and performance


2️⃣ Goals of System Design 🎯

The main objectives are:

  • Scalability – System should handle increasing users or data.

  • Reliability – System should work consistently without failures.

  • Availability – System should be accessible most of the time.

  • Performance – System should respond quickly.

  • Maintainability – Easy to update and fix.

  • Security – Protect data and system resources.


3️⃣ Types of System Design

1. High-Level Design (HLD)

This describes the overall architecture of the system.

It includes:

  • System architecture

  • Major components

  • Communication between services

  • Database selection

  • Technology stack

Example components:

  • Frontend

  • Backend

  • Database

  • API Gateway

  • Load Balancer

  • Cache

Example:
Designing a YouTube-like system with:

  • Video upload service

  • Video streaming service

  • CDN

  • Metadata database


2. Low-Level Design (LLD)

This focuses on detailed implementation of each component.

It includes:

  • Class diagrams

  • Data structures

  • Algorithms

  • Database schema

  • API definitions

Example:

  • User class

  • Video class

  • Authentication module


4️⃣ Key Components in System Design

1. Load Balancer ⚖️

Distributes traffic across multiple servers.

Example:
If 1 million users access a website, load balancer distributes requests across servers.


2. Database 🗄️

Stores system data.

Types:

  • SQL databases – MySQL, PostgreSQL

  • NoSQL databases – MongoDB, Cassandra


3. Cache ⚡

Stores frequently accessed data to reduce database load.

Example tools:

  • Redis

  • Memcached


4. Message Queue 📩

Used for asynchronous communication.

Examples:

  • Kafka

  • RabbitMQ

  • AWS SQS


5. Microservices 🧩

Large systems are divided into small independent services.

Example:

  • User service

  • Payment service

  • Notification service


5️⃣ Important Concepts in System Design

Scalability

Ability of system to handle increasing load.

Types:

  • Vertical Scaling – Increase server power.

  • Horizontal Scaling – Add more servers.


Availability

System should be accessible even if some servers fail.

Example:
Using multiple servers and replication.


Consistency

All users should see the same data at the same time.

Example:
Bank balance updates.


Fault Tolerance

System should continue working even if some components fail.


6️⃣ Example – Simple System Design

Designing a URL Shortener (like TinyURL)

Components:

  1. User enters long URL

  2. Backend generates short code

  3. Database stores mapping

  4. When user visits short link → redirect to original URL

Architecture:

User → API Server → Database → Redirect Service


7️⃣ Why System Design is Important

  • Helps build large-scale applications

  • Improves performance and scalability

  • Ensures system reliability

  • Makes development organized and maintainable

Examples of systems requiring good design:

  • Social media platforms

  • Banking systems

  • E-commerce websites

  • Streaming platforms


One Line Summary:

System Design is the process of defining the architecture and components of a system to build scalable, reliable, and efficient software.



📚 LLD vs DSA

1️⃣ What is LLD (Low Level Design)?

Low Level Design (LLD) focuses on designing the internal structure of a software system using classes, objects, and relationships.

It describes how the system components are implemented in code.

LLD mainly deals with:

  • Class design

  • Object interactions

  • Design patterns

  • UML diagrams

  • Code structure

Example

Designing a Parking Lot System

You design:

  • Vehicle class

  • ParkingSpot class

  • ParkingTicket

  • Payment

You decide:

  • attributes

  • methods

  • relationships between classes

Example code idea:

class Car extends Vehicle {
    String licensePlate;
}

So LLD answers:

👉 How should we structure the code?


2️⃣ What is DSA (Data Structures & Algorithms)?

DSA focuses on solving computational problems efficiently using data structures and algorithms.

It deals with:

  • Optimizing time complexity

  • Optimizing memory usage

  • Writing efficient logic

Common Data Structures

  • Arrays

  • Linked Lists

  • Stacks

  • Queues

  • Trees

  • Graphs

  • Hash Maps

Algorithms

  • Sorting

  • Searching

  • Recursion

  • Dynamic Programming

  • Greedy algorithms

  • Graph algorithms

Example:

def binary_search(arr, target):

DSA answers:

👉 How to solve a problem efficiently?


⚖️ LLD vs DSA Comparison

AspectLLDDSA
Full FormLow Level DesignData Structures & Algorithms
FocusCode designProblem solving
LevelSystem architecture inside modulesAlgorithmic logic
Used forDesigning software systemsOptimizing solutions
ConceptsOOP, design patterns, UMLTrees, graphs, DP, sorting
Interview typeDesign roundCoding round
ExampleDesign Parking LotFind shortest path

🧠 Simple Analogy

Imagine building a house 🏠

DSA → How to efficiently move bricks and materials
LLD → How rooms, doors, and windows should be structured


🧑‍💻 Example Difference

Problem: Build a Ride Booking App (like Uber)

DSA Approach

Find:

  • shortest path between locations

  • nearest driver

Algorithms used:

  • Dijkstra

  • Graph search


LLD Approach

Design classes:

User
Driver
Ride
Payment
Location

Define relationships:

User -> Request Ride
Driver -> Accept Ride
Ride -> Payment

🎯 When Each is Used

DSA

Used in:

  • Coding interviews

  • Competitive programming

  • Performance optimization

Companies ask:

  • Google

  • Amazon

  • Meta

  • Microsoft


LLD

Used in:

  • Backend engineering

  • Software architecture interviews

  • Real system building

Companies ask:

  • Amazon

  • Uber

  • Flipkart

  • Swiggy


📘 Three Pillars of LLD (Low Level Design)

In Low Level Design (LLD), the foundation is built on Object-Oriented Programming (OOP) principles.

The three core pillars are:

  1. Encapsulation

  2. Abstraction

  3. Polymorphism

(⚠️ Note: Some people say 4 pillars by including Inheritance separately. But commonly in LLD discussions, these three are emphasized strongly.)


1️⃣ Encapsulation 🔒

Definition:

Encapsulation means bundling data (variables) and methods (functions) together inside a class and restricting direct access to internal details.

Why?

  • Protect data

  • Improve security

  • Prevent accidental modification

Example:

class BankAccount {
    private double balance;

    public void deposit(double amount) {
        balance += amount;
    }

    public double getBalance() {
        return balance;
    }
}

Here:

  • balance is private

  • Can only access via methods

👉 Real-life example:
ATM machine — you cannot directly access bank database.


2️⃣ Abstraction 🎭

Definition:

Abstraction means hiding complex implementation details and showing only essential features.

You expose what to do, not how it works internally.

Why?

  • Reduce complexity

  • Improve maintainability

  • Loose coupling

Example:

interface Payment {
    void pay();
}

Implementation:

class CreditCardPayment implements Payment {
    public void pay() {
        // complex logic
    }
}

User only calls:

payment.pay();

User does not know internal logic.

👉 Real-life example:
Driving a car — you press accelerator, but you don’t know engine internals.


3️⃣ Polymorphism 🔄

Definition:

Polymorphism means one interface, multiple implementations.

Same method name behaves differently depending on object.

Types:

  1. Method Overloading (Compile-time)

  2. Method Overriding (Runtime)

Example:

class Animal {
    void sound() {
        System.out.println("Animal sound");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Bark");
    }
}

Here:
sound() behaves differently for different objects.

👉 Real-life example:
Payment method — Credit Card, UPI, Net Banking
Same pay() method → different behavior.


🎯 Why These 3 Are Important in LLD?

LLD is about:

  • Designing classes

  • Creating relationships

  • Writing scalable object-oriented code

These pillars help in:

  • Writing clean code

  • Applying design patterns

  • Making system flexible

  • Improving maintainability


🧠 Simple Summary

PillarMeaning
EncapsulationProtect and bundle data
AbstractionHide complexity
PolymorphismSame method, different behavior



📚 LLD vs HLD

1️⃣ What is HLD (High Level Design)?

High Level Design (HLD) describes the overall architecture of a system and how major components interact with each other.

It focuses on the big picture of the system.

HLD defines:

  • System architecture

  • Major modules/services

  • Data flow between services

  • Technology stack

  • Database selection

  • External integrations

Example

Designing Netflix

HLD will define:

  • User Service

  • Video Streaming Service

  • Recommendation Service

  • Database

  • CDN

  • Load Balancer

Architecture example:

User → Load Balancer → API Server → Microservices → Database

👉 HLD answers:

“How the entire system is structured?”


2️⃣ What is LLD (Low Level Design)?

Low Level Design (LLD) focuses on detailed design of individual components inside the system.

It explains how each module will be implemented in code.

LLD defines:

  • Classes

  • Objects

  • Methods

  • Relationships between classes

  • Database schema

  • Algorithms used inside modules

Example

In Netflix Video Service

LLD will design classes like:

Video
User
Playlist
Subscription

Define:

  • attributes

  • methods

  • interactions between classes

👉 LLD answers:

“How exactly will the code be implemented?”


⚖️ LLD vs HLD Comparison

AspectHLDLLD
Full FormHigh Level DesignLow Level Design
FocusSystem architectureCode-level design
LevelMacro / Big pictureMicro / Detailed
ComponentsServices, databases, APIsClasses, objects, methods
DiagramsArchitecture diagramsClass diagrams, sequence diagrams
Used bySystem architectsDevelopers
GoalDefine system structureImplement system logic

🧠 Simple Example

Imagine building a food delivery app like Swiggy 🍔

HLD

Define modules:

  • User Service

  • Restaurant Service

  • Order Service

  • Payment Service

  • Delivery Tracking

Architecture:

Mobile App → API Gateway → Microservices → Database


LLD

Inside Order Service, design:

Classes:

Order
OrderItem
Cart
Payment
DeliveryAgent

Define:

  • attributes

  • methods

  • relationships


🏗️ Simple Analogy

Building a house 🏠

ConceptExample
HLDHouse blueprint (rooms, floors, layout)
LLDHow walls, wiring, plumbing are built

🎯 When Each is Used

HLD

Used for:

  • System architecture planning

  • Large scale systems

  • Microservices design

  • Cloud architecture


LLD

Used for:

  • Code implementation

  • Class design

  • Design patterns

  • Object relationships



📚 Common Reusable Algorithms in LLD

1️⃣ Sorting Algorithms

Sorting is frequently used in many systems such as:

  • Leaderboards

  • Product listings

  • Ranking systems

  • Log processing

Common algorithms:

  • Quick Sort

  • Merge Sort

  • Heap Sort

  • Bubble Sort (for small data)

Example (Python):

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]

Example use case:

  • Sorting orders by price

  • Sorting users by score


2️⃣ Searching Algorithms

Used when systems need to quickly find data.

Common algorithms:

  • Linear Search

  • Binary Search

  • Hash-based lookup

Example:

def binary_search(arr, target):
    left, right = 0, len(arr)-1

Use cases:

  • Searching product by ID

  • Finding user records

  • Querying sorted datasets


3️⃣ Caching Algorithms

Used to store frequently accessed data.

Common caching strategies:

  • LRU (Least Recently Used)

  • LFU (Least Frequently Used)

  • FIFO

Example use cases:

  • Web caching

  • Database query caching

  • API response caching

Example:
Redis cache in backend systems.


4️⃣ Rate Limiting Algorithms

Used to control number of requests a user can make.

Common algorithms:

  • Token Bucket

  • Leaky Bucket

  • Sliding Window

Example use cases:

  • API request limits

  • Login attempt restrictions

  • Payment request limits

Example:
Allow only 100 requests per minute per user.


5️⃣ Scheduling Algorithms

Used for task execution and resource allocation.

Common algorithms:

  • First Come First Serve (FCFS)

  • Round Robin

  • Priority Scheduling

Use cases:

  • CPU scheduling

  • Job processing

  • Task queues

Example:
Background job systems like Celery or Kafka consumers.


6️⃣ Graph Algorithms

Used when dealing with network relationships.

Common algorithms:

  • Dijkstra (shortest path)

  • BFS (Breadth First Search)

  • DFS (Depth First Search)

Use cases:

  • Google Maps routing

  • Social network connections

  • Recommendation systems


7️⃣ Load Balancing Algorithms

Used in distributed systems.

Common algorithms:

  • Round Robin

  • Least Connections

  • Weighted Round Robin

  • Consistent Hashing

Use cases:

  • Distributing traffic across servers

Example:
User request → Load Balancer → Multiple servers.


8️⃣ Retry Algorithms

Used for handling temporary failures.

Common strategies:

  • Fixed Retry

  • Exponential Backoff

  • Circuit Breaker

Use cases:

  • API failures

  • Network retry

  • Microservices communication


🎯 Why Reusable Algorithms Are Important in LLD

They help in:

  • Reducing duplicate code

  • Improving efficiency

  • Making systems scalable

  • Improving maintainability


🧠 Quick Summary Table

Algorithm TypeExampleUse Case
SortingMerge SortRanking, ordering
SearchingBinary SearchData lookup
CachingLRUFast access
Rate LimitingToken BucketAPI protection
SchedulingRound RobinTask management
GraphDijkstraRouting
Load BalancingLeast ConnectionsServer traffic


📘 UML Diagram

UML (Unified Modeling Language) is a standard visual language used to represent the design and structure of a software system.

It helps developers and architects visualize, design, and document software systems before implementing them.

UML diagrams show:

  • System components

  • Relationships between objects/classes

  • Data flow

  • Interaction between modules

In LLD and System Design interviews, UML diagrams are often used to explain system structure clearly.


🎯 Why UML Diagrams Are Important

UML diagrams help in:

  • Understanding system architecture

  • Communicating design with team members

  • Documenting software systems

  • Simplifying complex designs

  • Planning implementation


📊 Most Important Types of UML Diagrams

UML diagrams are mainly divided into two categories:

1️⃣ Structural Diagrams
2️⃣ Behavioral Diagrams


1️⃣ Class Diagram (Most Important for LLD)

A Class Diagram shows:

  • Classes

  • Attributes

  • Methods

  • Relationships between classes

It is the most commonly used diagram in Low Level Design.

Example

Parking System Classes

Car
-----
licensePlate
color
startEngine()

ParkingSpot
-----
spotNumber
isAvailable()

ParkingLot
-----
totalSpots
assignSpot()

Relationships between classes are also shown.

Relationships types

  • Association

  • Inheritance

  • Aggregation

  • Composition


2️⃣ Sequence Diagram

A Sequence Diagram shows how objects interact with each other over time.

It represents:

  • Order of operations

  • Message flow between objects

Example

Food Delivery Order Flow

User → App → Order Service → Payment Service → Restaurant

Sequence:

  1. User places order

  2. App sends request to Order Service

  3. Payment processed

  4. Order confirmed

This diagram focuses on interaction timeline.


3️⃣ Use Case Diagram

A Use Case Diagram shows how users interact with a system.

It identifies:

  • Actors (users or external systems)

  • System functionalities

Example

ATM System

Actors:

  • Customer

  • Bank System

Use cases:

  • Withdraw money

  • Deposit money

  • Check balance

Diagram concept:

Customer → Withdraw Money
Customer → Check Balance
Customer → Deposit Money

This diagram shows system functionalities from user's perspective.


4️⃣ Activity Diagram

An Activity Diagram represents the workflow of a system or process.

It is similar to a flowchart.

Example

Online Shopping Flow

Start
 ↓
Browse Products
 ↓
Add to Cart
 ↓
Make Payment
 ↓
Order Confirmation
 ↓
End

Used to visualize business processes or workflows.


5️⃣ Component Diagram

A Component Diagram shows different components of a system and how they interact.

Example system components:

Frontend
Backend API
Database
Payment Gateway
Notification Service

This is commonly used in High Level Design (HLD).


6️⃣ Deployment Diagram

A Deployment Diagram shows how software components are deployed on hardware infrastructure.

Example:

User Device
      ↓
Web Server
      ↓
Application Server
      ↓
Database Server

Used for cloud architecture and distributed systems.


🧠 Most Important UML Diagrams for Interviews

DiagramUsed in
Class DiagramLLD interviews
Sequence DiagramLLD + System Design
Use Case DiagramRequirement analysis
Activity DiagramWorkflow modeling
Component DiagramHLD
Deployment DiagramInfrastructure design

⭐ Quick Summary

UML DiagramPurpose
Class DiagramStructure of classes
Sequence DiagramInteraction between objects
Use Case DiagramUser-system interaction
Activity DiagramWorkflow
Component DiagramSystem components
Deployment DiagramSystem deployment

🎯 One-Line Definition

UML diagrams are visual representations used to design and document software systems and their interactions.



3 MOST IMPORTANT UML diagrams used in LLD interviews with simple examples. 

1️⃣ Class Diagram
2️⃣ Sequence Diagram
3️⃣ State Machine Diagram


1️⃣ Class Diagram (Most Important in LLD)

A Class Diagram represents the structure of the system.

It shows:

  • Classes

  • Attributes

  • Methods

  • Relationships between classes

Basic Structure

-----------------
Class Name
-----------------
Attributes
-----------------
Methods
-----------------

Example: Parking Lot System

Vehicle
----------------
vehicleNumber
vehicleType
----------------
park()
unpark()
ParkingSpot
----------------
spotId
isAvailable
----------------
assignVehicle()
removeVehicle()
ParkingLot
----------------
totalSpots
availableSpots
----------------
addSpot()
getFreeSpot()

Relationship Example

Vehicle  ---- parked in ----> ParkingSpot
ParkingLot ---- contains ----> ParkingSpot

Types of Relationships

RelationshipMeaning
AssociationOne class uses another
InheritanceChild class inherits parent
AggregationWeak "has-a" relationship
CompositionStrong "part-of" relationship

Example:

Car → Vehicle (Inheritance)
ParkingLot → ParkingSpot (Composition)

2️⃣ Sequence Diagram

A Sequence Diagram shows how objects interact step-by-step over time.

It focuses on message flow between components.

Key Elements

  • Actor

  • Objects

  • Messages

  • Timeline (top → bottom)


Example: Food Ordering System

Objects involved:

User
MobileApp
OrderService
PaymentService
Restaurant

Sequence Flow:

User → MobileApp : Place Order
MobileApp → OrderService : Create Order
OrderService → PaymentService : Process Payment
PaymentService → OrderService : Payment Success
OrderService → Restaurant : Send Order
Restaurant → OrderService : Order Accepted
OrderService → MobileApp : Order Confirmed

Important point:

Sequence diagrams show how the system behaves during execution.


3️⃣ State Machine Diagram

A State Machine Diagram shows different states of an object and how it changes from one state to another.

It is useful for systems where objects have lifecycle states.


Example: Order in Food Delivery

States:

Order Created
↓
Payment Completed
↓
Restaurant Preparing
↓
Out for Delivery
↓
Delivered

State diagram concept:

[Created]
     ↓
[Paid]
     ↓
[Preparing]
     ↓
[Out for Delivery]
     ↓
[Delivered]

Another example:

ATM Transaction

Idle
↓
Card Inserted
↓
PIN Verified
↓
Transaction Processing
↓
Cash Dispensed
↓
Completed

🧠 When to Use Each Diagram

DiagramUsed For
Class DiagramSystem structure
Sequence DiagramInteraction flow
State MachineObject lifecycle

📊 Simple Real Example (Ride Booking App)

Class Diagram

Classes:

User
Driver
Ride
Payment
Location

Sequence Diagram

User → App : Request Ride
App → RideService : Find Driver
RideService → Driver : Ride Request
Driver → RideService : Accept
RideService → App : Ride Confirmed

State Diagram (Ride Status)

Requested
↓
Driver Assigned
↓
Driver Arrived
↓
Ride Started
↓
Ride Completed

⭐ Golden Rule for LLD Interviews

If asked to design a system:

Step 1 → Identify entities/classes
Step 2 → Draw Class Diagram
Step 3 → Show Sequence Diagram
Step 4 → Explain State transitions

This is exactly how Amazon / Uber / Flipkart LLD interviews are done.


Composition vs Association vs Aggregation in UML 📘


📘 1️⃣ Association

Definition

Association represents a general relationship between two classes where objects interact with each other.

It simply means one object uses another object.

Key Points

  • Weak relationship

  • Both objects can exist independently

  • No ownership

Example

Teacher and Student

A teacher teaches students, but both can exist independently.

Teacher -------- Student

Code Example

class Student {
    String name;
}

class Teacher {
    void teach(Student s) {
        System.out.println("Teaching student");
    }
}

Here:

  • Teacher uses Student

  • Student can exist without Teacher


📘 2️⃣ Aggregation

Definition

Aggregation is a special type of association that represents a "has-a" relationship where one class contains another class, but both can exist independently.

It is a weak ownership relationship.

Key Points

  • "Has-a" relationship

  • Objects can exist separately

  • Parent does not control child lifecycle

UML Symbol

Aggregation uses hollow diamond (◇)

Department ◇------ Teacher

Example

Department and Teachers

A department has teachers, but teachers can exist without the department.

Code Example

class Teacher {
    String name;
}

class Department {
    List<Teacher> teachers;
}

Here:

  • Department has teachers

  • Teachers can exist independently


📘 3️⃣ Composition

Definition

Composition is a strong form of aggregation where the child object cannot exist without the parent object.

It represents strong ownership.

Key Points

  • Strong "part-of" relationship

  • Child object depends on parent

  • If parent is deleted, child is also deleted

UML Symbol

Composition uses filled diamond (◆)

House ◆------ Room

Example

House and Rooms

Rooms cannot exist without a house.

Code Example

class Room {
}

class House {
    private Room room;

    House() {
        room = new Room();
    }
}

If House is destroyed → Room is destroyed.


📊 Comparison Table

FeatureAssociationAggregationComposition
Relationship typeGeneralHas-aStrong part-of
OwnershipNo ownershipWeak ownershipStrong ownership
DependencyIndependentIndependentDependent
LifecycleSeparateSeparateChild depends on parent
UML SymbolLineHollow Diamond ◇Filled Diamond ◆

🧠 Simple Real-Life Examples

RelationshipType
Doctor treats PatientAssociation
Team has PlayersAggregation
House has RoomsComposition

🎯 Interview Tip

Interviewers often ask:

Difference between Aggregation and Composition

Best answer:

  • Aggregation → weak "has-a" relationship

  • Composition → strong "part-of" relationship where child cannot exist without parent

Example:

Car ◇ Engine  → Aggregation
Human ◆ Heart → Composition

⭐ One-Line Summary

  • Association → objects are related

  • Aggregation → objects have weak ownership

  • Composition → objects have strong ownership and lifecycle dependency



SOLID = 5 design principles that help write maintainable, scalable, and flexible code.

S → Single Responsibility Principle
O → Open Closed Principle
L → Liskov Substitution Principle
I → Interface Segregation Principle
D → Dependency Inversion Principle

1️⃣ Single Responsibility Principle (SRP)

Definition

A class should have only one reason to change.

This means a class should do only one job.

If a class handles multiple responsibilities, it becomes hard to maintain.


❌ Bad Example (Violates SRP)

class Report:
    def generate_report(self):
        print("Generating report")

    def save_to_file(self):
        print("Saving report to file")

    def send_email(self):
        print("Sending report via email")

Problem:

Report class is doing three responsibilities:

  • Generating report

  • Saving report

  • Sending email

If email logic changes → this class must change.


✅ Good Example (Follow SRP)

class Report:
    def generate(self):
        print("Generating report")


class ReportSaver:
    def save(self, report):
        print("Saving report")


class EmailSender:
    def send(self, report):
        print("Sending email")

Now each class has one responsibility.

Benefits:

  • Easier testing

  • Easier maintenance

  • Better modular design


2️⃣ Open Closed Principle (OCP)

Definition

Software entities should be:

Open for extension
Closed for modification

Meaning:

  • You should add new functionality without modifying existing code.


❌ Bad Example

class PaymentProcessor:
    def process(self, payment_type):
        if payment_type == "credit":
            print("Processing credit card")
        elif payment_type == "paypal":
            print("Processing PayPal")

Problem:
If a new payment method comes (UPI), you must modify this class.


✅ Good Example (Using Polymorphism)

class Payment:
    def process(self):
        pass


class CreditCardPayment(Payment):
    def process(self):
        print("Processing credit card")


class PaypalPayment(Payment):
    def process(self):
        print("Processing PayPal")

Usage:

def make_payment(payment: Payment):
    payment.process()

Now adding new payment:

class UpiPayment(Payment):
    def process(self):
        print("Processing UPI")

No existing code changed ✅


3️⃣ Liskov Substitution Principle (LSP)

Definition

Subclasses should be replaceable with their parent class without breaking the program.

If class B inherits class A, then B should behave like A.


❌ Bad Example

Classic example: Square vs Rectangle

class Rectangle:
    def set_width(self, width):
        self.width = width

    def set_height(self, height):
        self.height = height


class Square(Rectangle):
    def set_width(self, width):
        self.width = self.height = width

Problem:

Square changes behavior of Rectangle.

This breaks expectations.


✅ Good Example

Separate classes.

class Shape:
    def area(self):
        pass


class Rectangle(Shape):
    def __init__(self, w, h):
        self.w = w
        self.h = h

    def area(self):
        return self.w * self.h


class Square(Shape):
    def __init__(self, s):
        self.s = s

    def area(self):
        return self.s * self.s

Now both can replace Shape safely.


4️⃣ Interface Segregation Principle (ISP)

Definition

Clients should not be forced to depend on methods they do not use.

Better to have multiple small interfaces rather than one large interface.

Python does not have strict interfaces like Java, but we use abstract classes.


❌ Bad Example

class Worker:
    def work(self):
        pass

    def eat(self):
        pass

Now consider:

HumanWorker → works + eats
RobotWorker → works only

Robot doesn’t need eat().


✅ Good Example

Split interfaces.

class Workable:
    def work(self):
        pass


class Eatable:
    def eat(self):
        pass

Now:

class Human(Workable, Eatable):
    def work(self):
        print("Working")

    def eat(self):
        print("Eating")


class Robot(Workable):
    def work(self):
        print("Working")

Robot no longer forced to implement eat().


5️⃣ Dependency Inversion Principle (DIP)

Definition

High-level modules should not depend on low-level modules.

Both should depend on abstractions.


❌ Bad Example

class MySQLDatabase:
    def connect(self):
        print("Connecting to MySQL")


class Application:
    def __init__(self):
        self.db = MySQLDatabase()

Problem:
Application depends directly on MySQL.

If you switch to PostgreSQL → code must change.


✅ Good Example

class Database:
    def connect(self):
        pass

Implementations:

class MySQLDatabase(Database):
    def connect(self):
        print("MySQL connection")


class PostgresDatabase(Database):
    def connect(self):
        print("Postgres connection")

Application:

class Application:
    def __init__(self, db: Database):
        self.db = db

    def start(self):
        self.db.connect()

Usage:

db = MySQLDatabase()
app = Application(db)
app.start()

Now database can be swapped easily.


📊 SOLID Summary Table

PrincipleMeaning
SRPOne class → one responsibility
OCPExtend without modifying
LSPChild classes must behave like parent
ISPPrefer small interfaces
DIPDepend on abstractions

🧠 Real World Example (Web Backend)

PrincipleExample
SRPUserService handles user logic only
OCPAdd new payment methods without modifying core code
LSPAll shapes can be treated as Shape
ISPSeparate interfaces for payment/refund
DIPApplication depends on database interface

⭐ One-Line Memory Trick

S → Single responsibility
O → Open for extension
L → Liskov substitution
I → Interface segregation
D → Dependency inversion


Comments

Popular posts from this blog

Resume Work and Project Details

Time Series and MMM basics

LINEAR REGRESSION