SOLID, Critically

Each principle by the problem it addresses, a real example, a real misuse and a counterexample. Useful heuristics, not laws, and the difference matters.

SOLID, Read Honestly

Five heuristics about the cost of change, collected over two decades, of genuinely unequal quality — and none of them a law.

Q · What do the five principles actually have in common, and how much weight can each one bear?
Single Responsibility, Critically

"A coherent reason to change" is the useful reading. "One thing" is the one that produces a hundred classes that each do nothing.

Q · What counts as one responsibility, when every class can be described as doing one thing or as doing five?
Open/Closed, Critically

Prefer designs where common, observed variation can be added without rewriting stable core logic. Not "never modify existing code" — that reading builds plugin machinery for variation that never arrives.

Q · When is it worth making a piece of code extensible, given that extensibility is only ever cheap for the variation you predicted?
Liskov Substitution, Critically

A subtype must keep every promise callers rely on from the abstraction. It is a behavioural contract, not a fact about inheritance syntax — and it is the sharpest of the five.

Q · What exactly does a caller rely on when it holds a reference to an abstraction, and how would I know if an implementation broke it?
Interface Segregation, Critically

A consumer should depend on the smallest contract that serves it. That is a statement about coupling, not a rule that interfaces must be small.

Q · How wide should an interface be, when narrowing it means more types and widening it means more consumers affected by every change?
Dependency Inversion, Critically

The idea is which module declares the interface. The cargo cult is a container, an interface per class, and the same dependency graph as before.

Q · We installed a DI container and registered everything. Have we inverted any dependencies?
How SOLID Gets Misused

An interface per class, layers that pass data unchanged, abstractions with one implementation — and the critiques of SOLID that are strong enough to deserve a straight answer.

Q · This codebase followed the principles carefully and is miserable to change. What went wrong, and how much of it is the principles' fault?