Files

86 lines
3.6 KiB
Markdown

# SOLID Principles — Overview
The SOLID principles are five design guidelines that make object-oriented software easier to understand, maintain, and extend. They were promoted by Robert C. Martin (Uncle Bob) and have become foundational to professional software engineering.
## Quick-Reference Table
| Principle | Abbr. | One-Liner | Key Question |
|---|---|---|---|
| **Single Responsibility** | SRP | A class should have only one reason to change. | "Does this class do more than one job?" |
| **Open/Closed** | OCP | Open for extension, closed for modification. | "Can I add behavior without editing existing code?" |
| **Liskov Substitution** | LSP | Subtypes must be substitutable for their base types. | "Can I swap in a subclass without breaking anything?" |
| **Interface Segregation** | ISP | No client should depend on methods it does not use. | "Is any implementer forced to stub out unused methods?" |
| **Dependency Inversion** | DIP | Depend on abstractions, not concretions. | "Does my high-level logic import low-level details?" |
## Decision Tree
Use the following decision tree when reviewing or designing code:
```
START: You are looking at a class / module / struct
├─ Does it have more than one reason to change?
│ YES → Apply SRP. Split into focused units.
│ NO ↓
├─ To add a new variant / behavior, must you edit existing code?
│ YES → Apply OCP. Introduce polymorphism or strategy.
│ NO ↓
├─ Can every subtype replace its parent without breaking callers?
│ NO → Apply LSP. Fix the inheritance hierarchy or use composition.
│ YES ↓
├─ Are implementers forced to depend on methods they don't use?
│ YES → Apply ISP. Break the interface into smaller, focused ones.
│ NO ↓
├─ Do high-level modules import / instantiate low-level concretions?
│ YES → Apply DIP. Introduce an abstraction and inject dependencies.
│ NO ↓
└─ Design looks solid. Review for other concerns (DRY, KISS, etc.)
```
## How the Principles Relate
```
SRP ──► keeps units small and focused
OCP ──► lets you extend those units safely
LSP ──► guarantees substitutability in those extensions
ISP ──► prevents bloated contracts between units
DIP ──► decouples the wiring so everything stays flexible
```
- **SRP + ISP** often work together: splitting a fat class (SRP) usually means splitting its interface too (ISP).
- **OCP + DIP** are natural partners: depending on abstractions (DIP) is *how* you achieve extension without modification (OCP).
- **LSP** is the safety net: it ensures that the polymorphism you rely on for OCP actually works correctly.
## When to Apply SOLID
**Apply aggressively when:**
- The codebase is long-lived and maintained by a team
- Requirements change frequently
- You are building libraries or frameworks consumed by others
- Testability is a priority
**Apply with restraint when:**
- Writing a one-off script or prototype
- The domain is tiny and unlikely to change
- Over-abstraction would add complexity without benefit
- You are in the earliest exploratory phase of a project
## Files in This Directory
| File | Principle |
|---|---|
| [single-responsibility.md](single-responsibility.md) | Single Responsibility Principle |
| [open-closed.md](open-closed.md) | Open/Closed Principle |
| [liskov-substitution.md](liskov-substitution.md) | Liskov Substitution Principle |
| [interface-segregation.md](interface-segregation.md) | Interface Segregation Principle |
| [dependency-inversion.md](dependency-inversion.md) | Dependency Inversion Principle |