SOLID Principles
SOLID Principles
Section titled “SOLID Principles”Introduction
Section titled “Introduction”SOLID is an acronym for five fundamental principles of object-oriented design. These principles guide developers to create code that is maintainable, scalable, and flexible.
The term was coined by Robert C. Martin (Uncle Bob) in the early 2000s.
| Letter | Principle | Core Idea |
|---|---|---|
| S | Single Responsibility | A class should have one reason to change |
| O | Open/Closed | Open for extension, closed for modification |
| L | Liskov Substitution | Subtypes must be substitutable for their base types |
| I | Interface Segregation | Many specific interfaces are better than one general interface |
| D | Dependency Inversion | Depend on abstractions, not concrete implementations |
Visual Overview
Section titled “Visual Overview”graph TD SOLID["SOLID Principles"] SOLID --> S["S — Single Responsibility<br/>One job per class"] SOLID --> O["O — Open/Closed<br/>Extend, don't modify"] SOLID --> L["L — Liskov Substitution<br/>Substitute freely"] SOLID --> I["I — Interface Segregation<br/>Small, focused interfaces"] SOLID --> D["D — Dependency Inversion<br/>Depend on abstractions"]S — Single Responsibility Principle (SRP)
Section titled “S — Single Responsibility Principle (SRP)”A class should have only one reason to change.
Problem
Section titled “Problem”// ❌ Violates SRP — three responsibilitiesclass ReportManager { generateReport(data) { /* ... */ } printReport(report) { /* ... */ } emailReport(report) { /* ... */ }}Solution
Section titled “Solution”// ✅ Follows SRPclass ReportGenerator { generate(data) { /* ... */ } }class ReportPrinter { print(report) { /* ... */ } }class EmailService { send(to, report) { /* ... */ } }O — Open/Closed Principle (OCP)
Section titled “O — Open/Closed Principle (OCP)”Classes should be open for extension but closed for modification.
Problem
Section titled “Problem”// ❌ Violates OCP — adding new shape requires modificationclass AreaCalculator { calculate(shape) { if (shape.type === "circle") { return Math.PI * shape.radius ** 2; } else if (shape.type === "rectangle") { return shape.width * shape.height; } // Need to add more 'else if' for new shapes! }}Solution
Section titled “Solution”// ✅ Follows OCPclass Shape { area() { return 0; } }class Circle extends Shape { area() { return Math.PI * this.radius ** 2; } }class Rectangle extends Shape { area() { return this.w * this.h; } }// New shape — no existing code modified!class Triangle extends Shape { area() { return (this.b * this.h) / 2; } }L — Liskov Substitution Principle (LSP)
Section titled “L — Liskov Substitution Principle (LSP)”Subtypes must be substitutable for their base types.
Problem
Section titled “Problem”class Rectangle { setWidth(w) { this.width = w; } setHeight(h) { this.height = h; } area() { return this.width * this.height; }}
class Square extends Rectangle { setWidth(w) { this.width = w; this.height = w; } // Changes behavior! setHeight(h) { this.width = h; this.height = h; } // Changes behavior!}Solution
Section titled “Solution”Separate interfaces for different shapes — don’t force Square to inherit from Rectangle.
I — Interface Segregation Principle (ISP)
Section titled “I — Interface Segregation Principle (ISP)”Many specific interfaces are better than one general interface.
Problem
Section titled “Problem”class MultiFunctionDevice { print() { throw "Not implemented"; } scan() { throw "Not implemented"; } fax() { throw "Not implemented"; }}Solution
Section titled “Solution”class Printer { print() { /* ... */ } }class Scanner { scan() { /* ... */ } }class SimplePrinter extends Printer { print() { /* works */ } }D — Dependency Inversion Principle (DIP)
Section titled “D — Dependency Inversion Principle (DIP)”Depend on abstractions, not concrete implementations.
Problem
Section titled “Problem”class UserService { constructor() { this.db = new MySQLDatabase(); // Direct dependency! }}Solution
Section titled “Solution”class UserService { constructor(database) { this.db = database; // Depends on abstraction }}Benefits of SOLID
Section titled “Benefits of SOLID”| Principle | Benefit |
|---|---|
| SRP | Easier to understand, test, and maintain |
| OCP | Add features without breaking existing code |
| LSP | Inheritance hierarchies are reliable |
| ISP | Classes aren’t forced to implement unused methods |
| DIP | Loose coupling, easy to swap implementations |
Summary
Section titled “Summary”| Principle | One-Liner |
|---|---|
| S | One class = one job |
| O | Extend without modifying |
| L | Don’t break parent contracts |
| I | Small, focused interfaces |
| D | Depend on abstractions |
Previous Topic: Design Principles → Next Topic: Design Principles (DRY, KISS, YAGNI) →