Why Learn SOLID Principles
Why Learn SOLID Principles
SOLID is five design principles, coined by Robert C. Martin, that answer one recurring question: how do I structure classes so the system stays changeable as it grows? Software rarely dies from a bad first version. It dies from the tax on every subsequent change — a one-line feature that forces edits in nine files, a bug fix that breaks an unrelated screen, a test you cannot write because the class reaches out to a live database. SOLID is a vocabulary for the design smells behind that tax and a set of moves to relieve it.
For a senior interview, SOLID matters less as five acronyms to recite and more as a shared language. When you say "that violates the Single Responsibility Principle" in a design review, you compress a paragraph of reasoning into three letters. Interviewers use it to probe whether you can name why a design is fragile, not just feel that it is.
(1) Intuition — the problem it solves
Every non-trivial class has two audiences: the code that uses it, and the developers who must change it later. The enemy of both is coupling — when a change in one place ripples to another that had no logical reason to care. SOLID is fundamentally about managing dependencies: which module knows about which, and in what direction.
The failure mode SOLID targets is the rigid, fragile, immobile design: rigid because one change forces a cascade, fragile because changes break distant things, immobile because you cannot lift a piece out to reuse or test it. Each principle attacks one flavor of that coupling.
(2) Precise definition — the five principles
- S — Single Responsibility Principle (SRP): a class should have one reason to change. "Reason" means one actor or stakeholder. If the billing team and the reporting team both force edits to the same class, it has two responsibilities.
- O — Open/Closed Principle (OCP): open for extension, closed for modification. You should add new behavior by adding new code (a new subtype or strategy), not by editing existing, tested code.
- L — Liskov Substitution Principle (LSP): a subtype must be usable anywhere its supertype is expected, without surprising the caller. Overrides may not strengthen preconditions or weaken postconditions.
- I — Interface Segregation Principle (ISP): clients should not be forced to depend on methods they don't use. Prefer several small, role-specific interfaces over one fat one.
- D — Dependency Inversion Principle (DIP): high-level policy should depend on abstractions, not on low-level details. Both should depend on interfaces, and the abstraction is owned by the high-level module.
The connective tissue: OCP is the goal (extend without editing), and LSP, ISP, and DIP are the mechanisms that make OCP achievable through polymorphism. SRP keeps each unit small enough that the others are even possible.
(3) Concrete example
A single OrderService that computes totals, saves to a specific database, and emails a receipt violates SRP (three actors), DIP (depends on concrete MySqlOrderRepo), and OCP (a new notification channel means editing the class). Splitting responsibilities and depending on abstractions fixes all three at once:
// High-level policy depends only on abstractions (DIP)
interface OrderRepository { void save(Order o); }
interface Notifier { void send(Order o); }
final class OrderService {
private final OrderRepository repo;
private final Notifier notifier;
OrderService(OrderRepository repo, Notifier notifier) {
this.repo = repo; // injected, not new'd
this.notifier = notifier;
}
void place(Order order) { // one reason to change: order flow
repo.save(order);
notifier.send(order);
}
}
// Extend by ADDING code, never editing OrderService (OCP)
class EmailNotifier implements Notifier { /* ... */ }
class SmsNotifier implements Notifier { /* ... */ }Now adding SMS is a new class wired in at construction; OrderService stays untouched and is trivially unit-testable with fakes. This applies whenever a class both decides something and talks to a volatile detail (DB, queue, third-party API) — invert that dependency.
Dependency direction after inversion
(4) When to use / when NOT
SOLID pays off where change is expected: volatile dependencies, multiple stakeholders, or points you know will vary (payment providers, storage backends, notification channels). The named alternative is the concrete, procedural design — do the work inline, new your dependencies directly. That is genuinely better when the code is stable, small, or a throwaway script: fewer indirections, easier to read top-to-bottom.
- Do not invert a dependency that will never change. An interface with exactly one implementation forever is speculative generality — it adds a hop and a file for no payoff. Introduce the abstraction when the second reason appears, not on suspicion.
- SRP has a cost: splitting one class into five means five things to navigate. Over-applied, it produces a fog of anemic one-method classes. Balance against cohesion — things that change together should live together.
- OCP is a trade against YAGNI. Every extension point you build "just in case" is complexity you pay for now for a flexibility you may never use. Prefer refactoring to the abstraction when the change actually arrives.
The senior judgment is knowing SOLID is a set of tensions to balance, not laws to maximize. DRY, YAGNI, and high cohesion pull against blind SOLID application, and a good design negotiates among them.
(5) Pitfalls / what interviewers probe
- Reciting vs. applying. The follow-up is always "show me a violation and fix it." Have a concrete before/after (like the
OrderServiceabove) ready. - SRP's "responsibility" is vague. Strong answers define it as one reason to change tied to one actor, not "one method" or "one thing."
- The classic LSP trap:
Square extends Rectangle. OverridingsetWidthto also set height breaks a caller that assumes width and height are independent. Interviewers love this to test whether you grasp behavioral, not just structural, subtyping. - Confusing DIP with dependency injection. DI is a mechanism (passing dependencies in); DIP is the principle (depend on abstractions, and the high-level module owns the interface). You can do DI and still violate DIP by injecting a concrete class.
- Over-engineering. A senior candidate volunteers the costs — indirection, YAGNI, cognitive load — rather than treating SOLID as an unqualified good. Naming the trade-off is the signal they want.
Key takeaways
- SOLID is five principles for managing dependencies so a system stays changeable — a shared vocabulary for design reviews, not trivia to recite.
- SRP: one reason (actor) to change. OCP: extend by adding, not editing. LSP: subtypes must honor the supertype's contract. ISP: small role-specific interfaces. DIP: depend on abstractions the high-level module owns.
- OCP is the goal; LSP, ISP, and DIP are the polymorphic mechanisms that achieve it; SRP keeps units small enough to make it work.
- Apply where change is expected; the concrete/procedural alternative wins for stable, small, or throwaway code. Introduce abstractions on the second reason, not the first.
- SOLID trades against YAGNI, DRY, and cohesion — senior judgment is balancing those tensions, not maximizing any single principle.
- Interviewers probe with the Square/Rectangle LSP trap, the DIP-vs-DI distinction, and whether you can name the costs of over-applying it.
🤖 Don't fully get this? Learn it with Claude
Stuck on Why Learn SOLID Principles? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Why Learn SOLID Principles** (OO & Low-Level Design) and want to truly understand it. Explain Why Learn SOLID Principles from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **Why Learn SOLID Principles** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **Why Learn SOLID Principles** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **Why Learn SOLID Principles** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.