Low Level DesignSOLID principles
SOLID principles
What the five SOLID principles are for, a one-line test for each, how they fit together, and when to ignore them. The starting point for the SOLID pages.
- Read first
- Object modeling
SOLID is five principles for arranging classes so that code stays easy to change. Robert Martin collected them in a 2000 paper, Design Principles and Design Patterns, and Michael Feathers later noticed their initials spelled a word. None of them is a law. Each one is a response to a specific way that object-oriented code gets hard to change, and each has a cost.
They matter for interviews because almost every low level design question is really a question about change. “Add a new vehicle type.” “Now support a second payment provider.” “Make the pricing configurable per lot.” Each follow-up tests whether your design bends in the right places. SOLID is the vocabulary for explaining why it does.
The five, in one line each
Section titled “The five, in one line each”| Principle | The question it asks | You’re breaking it when |
|---|---|---|
| Single responsibility | How many different groups ask for changes to this class? | A change for one team breaks something another team relies on |
| Open/closed | Can I add the next variant by adding code, not editing it? | Every new type means another branch in the same switch |
| Liskov substitution | Can every subtype be used wherever its parent is expected, with no surprises? | Callers check instanceof, or a subclass throws “not supported” |
| Interface segregation | Does each caller depend only on the methods it uses? | Classes implement methods that do nothing, just to satisfy an interface |
| Dependency inversion | Do business rules depend on details, or do details plug into business rules? | You can’t test the core logic without a real database or API |
How they fit together
Section titled “How they fit together”The five aren’t independent. In a real design they work as a chain: each one sets up the next.
A worked example from the parking lot: pricing changes for a
different reason than spot tracking, so it gets its own class (single responsibility). The lot
only needs “what does this ticket cost?”, so the interface has one method (interface
segregation). The lot depends on that interface, not on HourlyPricing (dependency inversion).
A weekend rate is a new class, with no edit to the lot (open/closed). And every pricing class
must return a real amount for any ticket, never throw “not supported” (Liskov substitution).
When to ignore them
Section titled “When to ignore them”Every principle adds structure, and structure has a cost: more types, more files, more indirection to follow when reading.
Lean away from them when:
- The code is small, young or short-lived. A script, a prototype, or a feature whose shape you don’t know yet. Wait for the second variant before adding an interface for it.
- There is one actor and one implementation, and no test needs a fake. An interface with one implementation that will never have a second is a cost with no benefit.
- The language has a lighter tool. A function parameter, a Go interface declared by the caller,
or a TypeScript union with an exhaustive
switchoften does the job of a class hierarchy, with less code. - The hot path needs speed. Virtual calls and small objects can matter in tight loops, though far less often than people assume. Measure first.
Commonly taught wrong
Section titled “Commonly taught wrong”In interviews
Section titled “In interviews”Interviewers rarely ask “what does the L stand for?” They create a situation where a principle matters and watch what you do.
Good. Now we want to support electric vehicle charging spots. Walk me through the changes.
Whether your design takes the change as new classes, plus one line of wiring. And whether you
can name why: the spot types sit behind an interface the lot depends on. The red flag is
answering with a list of if statements across three classes. So is reciting all five
principles, instead of showing the one that matters here.
When you explain a design choice, name the principle and the change it protects against, in one sentence. Then say what it costs: “Pricing is behind an interface, so a new rate is a new class. The cost is one more type to read.”
Reading order
Section titled “Reading order”Read them in the order of the acronym. But if you only have time for two, read single responsibility and dependency inversion. Those two drive most of the class splits in a low level design interview. The other three refine them.
Each page teaches its principle through three real examples at Easy, Medium and Hard. The level you pick is remembered across all the SOLID and design pattern pages.
The designbeyondcode digest, every Saturday
New deep dives, interview tips and site news in one short email. Free. Leave with one click.
We never sell or share your email. We only use it to send this newsletter.