Design Patterns Tutorial 0/70 lessons ~6 min read Lesson 9

    SOLID Principles Overview

    SOLID is the five-principle discipline that makes object-oriented design tractable at scale.

    Course progress0%
    Focus
    21 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    SOLID is the five-principle discipline that makes object-oriented design tractable at scale. Every GoF pattern assumes at least one SOLID principle; many patterns are SOLID made concrete. Strategy is OCP. Repository is DIP. Adapter design follows ISP.

    This lesson surveys all five — Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion — so you can name which principle a code review is really about.

    The story

    A senior engineer said: "Every code review I lose is because I named the wrong SOLID principle." Reviewers reject "this is bad" but accept "this violates ISP — clients depend on methods they don't use." Naming the principle wins arguments; vague disapproval doesn't.

    The business problem

    Without SOLID vocabulary, structural problems become personal taste battles:

    • Review gridlock: "I don't like this" vs "this violates DIP — tests need real Stripe."
    • Pattern misfires: Strategy applied without OCP evidence — abstraction earns no cost.
    • Knowledge gap: juniors recite SOLID definitions but can't apply them to real PRs.
    • Gatekeeping: "you violate LSP" without explaining production cost.

    The problem teams faced

    Teams that know SOLID definitions but not application hit these walls:

    • Cannot translate messy code into the specific principle violated.
    • Apply patterns without the underlying principle — benefits don't materialize.
    • Pick the wrong refactor because they misdiagnosed the violation.
    • Treat SOLID as dogma instead of cost/benefit judgment.

    Understanding the topic

    SOLID in one line each — memorize these, not acronyms alone:

    • S — Single Responsibility: one reason to change (one stakeholder).
    • O — Open/Closed: open for extension, closed for modification.
    • L — Liskov Substitution: subtypes honor the base contract.
    • I — Interface Segregation: clients don't depend on unused methods.
    • D — Dependency Inversion: depend on abstractions, not concretions.

    Internal architecture

    Production cost when violated:

    text
    SRP → shotgun surgery, merge conflicts, coupled tests
    OCP → edit core for every new variant, regression risk
    LSP → runtime surprises in callers, flaky polymorphism
    ISP → bloated mocks, NotSupportedException traps
    DIP → slow flaky tests, vendor lock-in, can't swap infra

    Visual explanation

    Three diagrams anchor SOLID for daily use. The first is the five-principle pipeline. The second maps violations to canonical fixes. The third connects each principle to patterns you'll use weekly.

    SOLID — five principles
    SRP
    One stakeholder
    OCP
    Extend, don't edit
    LSP
    Safe substitution
    ISP
    Small interfaces
    DIP
    Abstractions
    SRP and DIP appear most often in production code reviews.
    Violation → canonical fix
    God class
    SRP violation
    Extract Class
    Split by stakeholder
    Switch grows
    OCP violation
    Strategy
    Extension point
    Diagnose principle first — then pick refactor or pattern.
    SOLID → patterns
    OCP
    Strategy · Factory
    DIP
    Repository · Adapter
    ISP
    Role interfaces
    SRP
    Extract Class
    Patterns are SOLID applied to specific forces — learn both maps together.

    Informative example

    One class, multiple violations — common in legacy services:

    ts
    // ❌ Violates SRP + DIP + OCP
    class OrderService {
    async createOrder(dto: CreateOrderDto) {
    const client = new StripeClient(process.env.STRIPE_KEY); // DIP
    const total = this.calculateTotal(dto); // pricing logic mixed in
    if (dto.country === "DE") { /* tax rules */ } // OCP
    await db.query("INSERT INTO orders ...", dto); // SRP (persistence)
    await client.charge(total);
    await sendGrid.send(dto.email, "Thanks!"); // SRP (notify)
    }
    }
    // ✅ Direction: OrderService (orchestrate) + PricingStrategy + PaymentGateway
    // + OrderRepository + Notifier — each owned by one stakeholder

    Execution workflow

    1SOLID in code review
    1 / 5

    Read the diff

    Which modules changed and why?

    Context before judgment.

    Real-world use

    SonarQube flags SRP/DIP violations in Java/Kotlin repos. Microsoft .NET guidelines cite SOLID by name. FAANG senior loops expect you to identify violations and propose refactors on a whiteboard. Clean Architecture and Hexagonal are DIP at multiple layers — SOLID is the physics underneath.

    Production case study

    A B2B SaaS platform had 30% test flakiness:

    • Diagnosis: DIP violations — services constructed Stripe, Postgres, SendGrid inline.
    • Refactor: domain-owned interfaces + DI container + in-memory fakes in tests.
    • Outcome: test suite 10× faster; flakiness 30% → 0.5%; new test cost 30 min → 5 min.
    • Lesson: DIP is the highest-leverage SOLID principle for test velocity.

    Trade-offs

    • Pro: shared vocabulary converts taste into judgment.
    • Pro: each violation has a canonical fix path.
    • Con: dogmatic SOLID without context causes over-engineering.
    • Con: one smell may violate multiple principles — pick the most actionable name.

    Decision framework

    • Cite SOLID in reviews with production cost, not as gatekeeping.
    • Diagnose violation before naming a pattern refactor.
    • Skip SOLID lectures on throwaway scripts and prototypes.
    • In functional codebases, translate intent (SRP → small functions, DIP → pass deps).

    Best practices

    • Print the violation → fix map; tape it near your review checklist.
    • Ask "what changes if requirements change?" to surface OCP.
    • Ask "can we test without infra?" to surface DIP.
    • Tie each principle to a story from your codebase, not a textbook.

    Anti-patterns to avoid

    • SOLID-shaming without suggesting a concrete refactor.
    • Applying all five principles to a 30-line utility.
    • Interfaces on every class "for SOLID" with one implementation forever.

    Common mistakes

    • Overlapping violations — fix SRP first when god class hides everything.
    • Functional code with SOLID jargon that doesn't map — translate intent.
    • Confusing DIP with "use a DI framework" — constructor injection is enough at small scale.

    Debugging tips

    • Slow tests → scan for `new StripeClient` and `new Pool` in domain code (DIP).
    • Merge conflicts → git shortlog on the file (SRP).
    • Mocks with 20 stub methods → fat interface (ISP).

    Optimization strategies

    • Teach SOLID on real PRs, not slides — consequences stick, definitions don't.
    • For interviews, pick one principle and one violation story per company on your resume.

    Common misconceptions

    • Many believe SOLID is only for OOP. Intent translates — SRP to modules, DIP to injected deps, OCP to plug-in functions.
    • Many believe you must never violate SRP. Judgment — tiny cohesive classes can serve two tightly coupled reasons.
    • Related: following lessons dive deep into each letter.

    Advanced interview questions

    Interview Prep

    Practice concise answers, then expand each card for the explanation.

    3 questions
    1IntermediateQuestionWhich SOLID principle is violated most often?+

    Answer

    SRP — pressure to ship adds behavior to the nearest class. Fix: Extract Class, often then Strategy or Observer.

    Follow-up

    Walk through a real SRP refactor.
    2IntermediateQuestionDIP vs dependency injection?+

    Answer

    DIP is the principle (depend on abstractions). DI is the mechanism (someone wires concretes). DI containers automate; constructor injection suffices for small apps.

    Follow-up

    When is DI overkill?
    3AdvancedQuestionIs SOLID still relevant in Rust/Go?+

    Answer

    Intent yes, labels adapt. SRP → focused modules. OCP → traits/interfaces. DIP → depend on traits not structs. LSP → subtype contracts on interfaces.

    Follow-up

    Which translates worst?

    Summary

    You can name all five SOLID principles, map violations to fixes and patterns, and cite them in review with production cost. Next lessons go deep on each letter — start with SRP.

    Ready to mark this lesson complete?Track your journey across the entire course.