SOLID principles
Code is not hard to write. It is hard to change. The first version of any class is fine. The trouble starts at the ninth feature request, when a small change to tax rounding breaks PDF export and nobody can explain why those two things were connected.
SOLID is five rules of thumb about that. Robert C. Martin collected them around 2000, and Michael Feathers noticed a few years later that the first letters spell a word. Each rule makes one kind of change cheap.
Think of a file in a codebase you have worked on that everyone was afraid to touch. What made it scary? Write two specific things.
The five, on one screen
| Principle | In one line | The smell that tells you it is broken | |
|---|---|---|---|
| S | Single responsibility | One class, one team with a reason to change it. | A file that shows up in every pull request. |
| O | Open closed | Add behaviour by adding code, not by editing code that works. | An if ladder that grows by one rung per feature. |
| L | Liskov substitution | A subclass works anywhere its parent works. | A method that throws “not supported”. |
| I | Interface segregation | Nobody depends on methods they do not use. | Empty methods written to satisfy an interface. |
| D | Dependency inversion | Business logic depends on interfaces, not on the database. | new on a database or an API client inside business logic. |
The chef only cooks (S). A new dish goes on the menu without rebuilding the kitchen (O). A substitute cook can cover any shift (L). The waiter gets the menu, not the supplier invoices (I). And the kitchen is built around the gas connection, not around one brand of stove (D). Every page in this section goes back to one of those five sentences.
How they fit together
They are not five independent rules. Open closed is the goal: new behaviour should arrive as new code. Dependency inversion and Liskov substitution are how you get there, because you can only plug in a new class if callers depend on an interface, and only if every class behind that interface really honours it. Single responsibility and interface segregation keep the pieces small enough for that to work, one for classes and one for interfaces.
If you have read the OOP pages, you have already used most of this. Polymorphism is the mechanism. SOLID tells you where to put it.
Apply all five to a 40 line script and you get nine files, four interfaces, and a reader who cannot find where anything happens. The principles fix pain that comes from change. Where nothing is changing, there is no pain to fix. My rule: write the plain version first, and reach for a principle the second time a change hurts in the same place.
Name the principle
The five pages
Checkpoint
1. Which principle is most directly about being able to add a feature without editing existing, working code?
2. A subclass overrides a method to throw "not supported". Which principle does that break, and why does it matter?
3. You are writing a 60 line script that will run once to migrate data. How much SOLID does it need?
SOLID is five principles for keeping code cheap to change. Single responsibility: a class should have one reason to change, meaning one team that asks for changes to it. Open closed: new behaviour should come as new code, not as edits to code that works. Liskov substitution: a subclass has to work anywhere its parent does, with no surprises. Interface segregation: keep interfaces small so nobody implements or depends on methods they do not use. Dependency inversion: business logic depends on interfaces, and the database and vendors plug into those. They work together, open closed is the goal and the other four make it possible, and they are guidelines for code that changes, not rules for every file.
