SOLID Principles

These five software development principles are guidelines to follow when building software so that it is easier to scale and maintain. They were made popular by a software engineer, Robert C. Martinarrow-up-right.

circle-info

The SOLID Principles

TO MAKE EASIER AND SIMPLE TO FOLLOW.

  1. I WILL BE USING WORD "CLASS" FOR SIMPLICITY.

  2. THESE BELOW PRINCIPLES CAN ALSO BE APPLIED TO "FUNCTIONS", "METHOD" OR "MODULE".

S - Single Responsibility Principle (SRP)

A CLASS should only have one reason to change. i.e. one responsibility

Why: If a "CLASS" has multiple responsibilities, changes to one responsibility can unintentionally affect others, increasing the risk of bugs.

Goal: Separate behaviors so that changes in one area do not impact unrelated areas.

Example: A Report class should only handle report generation, not saving or emailing reports. Those should be separate classes.

Violates SRP: Report CLASS handles generating, saving, and emailing.

SRP-compliant: Separate classes for each responsibility


O - Open-Closed Principle (OCP)

A CLASS should be open for extension but closed for modification.

Why: Modifying existing code can introduce bugs in systems that rely on that code. Instead, extend functionality by adding new code.

Goal: Allow a class’s behavior to be extended without changing its existing code, reducing the risk of breaking other parts of the system.

Example: Add new features by creating subclasses or using interfaces, rather than altering the original class.

Violation: Adding new report formats requires modifying the existing class.

Correction: Extend functionality by adding new classes, not modifying existing ones.


L - Liskov Substitution Principle (LSP)

If S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program.

Why: If a subclass cannot perform the same actions as its parent, it can cause unexpected bugs.

Goal: Ensure that derived classes extend the base class without changing its expected behavior.

Example: If a Coffee class has a Cappuccino subclass, the subclass should behave like a Coffee In all contexts where Coffee is expected.

Violation: A subclass breaks the expected behavior of the base class.

Correction: The subclass can be used anywhere the base class is expected.


I - Interface Segregation Principle (ISP)

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

Why: Large, general-purpose interfaces force classes to implement unnecessary methods, leading to bloated and fragile code.

Goal: Split large interfaces into smaller, client-specific ones so that classes only implement what they need.

Example: Instead of one big interface for all printer functions, have separate interfaces for scanning, printing, and faxing.

Violation: A single interface forces classes to implement unused methods.

Correction: Split into smaller, focused interfaces.


D - Dependency Inversion Principle (DIP)

High-level modules should not depend on low-level modules. Both should depend on the abstraction.

Abstractions should not depend on details. Details should depend on abstractions.

circle-info

High-level Module(or Class): A Class that executes an action with a tool.

Low-level Module (or Class): The tool that is needed to execute the action

Abstraction: Represents an interface that connects the two Classes.

Details: How the tool works

Why: Direct dependencies between high-level and low-level modules make code rigid and hard to change.

Goal: Reduce coupling by introducing interfaces or abstract classes, making the system more flexible and testable.

Example: A LightSwitch class should depend on a SwitchableDevice interface, not directly on a LightBulb class.

Violation: High-level class depends directly on a low-level class.

Correction: Depending on an abstraction/interface.


Summary

Principle
Name
Key Idea

S

Single Responsibility

A class should have only one reason to change—one responsibility

O

Open-Closed

A class should be open for extension, but closed for modification

L

Liskov Substitution

Subclasses should be substitutable for their base classes without altering correctness

I

Interface Segregation

Classes should not be forced to depend on methods they do not use

D

Dependency Inversion

High-level modules should not depend on low-level modules; both should depend on abstractions

Last updated