Skip to main content

SOLID Principles in Depth

About this series

Knowing the definitions of the SOLID principles still leaves you undecided in real work. Should this class be split? Should you extract an interface when no extension point is in sight yet? Can this inheritance really be called substitutable? The definitions themselves do not answer these questions.

For each of the five principles, this series covers three things.

  • Why follow it — what cost the principle is trying to reduce
  • How it gets misused — what happens when you follow it too far
  • When it's OK to break it — the conditions under which not applying it is the sound call

Alongside that, it goes to primary sources to show who proposed each principle and when, and how each is reassessed today.

The verification standard for this series

Claims whose sources could not be confirmed are not written here. Where the original text was unreachable and only commentary articles were available, the text says so explicitly as a secondary source. Assertions of "best practice" or "industry standard" without a source are not used.

How this fits with the introductory article

The definitions of the five principles, and the rewrites from a violating example to an improved one, are covered by Clean Code Guide — SOLID Principles. Read that one first. This series takes that content as given and does not repeat it.

Clean Code Guide — SOLID PrinciplesThis series
QuestionWhat does the principle sayWhere did that definition come from, and where does it break
FormOne violating and one improved example per principleOriginal text / motivation / misuse / conditions for breaking it
Intended readerSomeone learning the five principles for the first timeSomeone who knows the definitions and is unsure how to apply them
LengthOne articleSeven chapters

Chapter outline

#ChapterWhat it covers
01Where the five principles came fromThe original text has four principles of class design and six of package design, and SRP is not among them
02SRP and over-splittingWho "a reason to change" actually refers to. What you lose when you split too far
03OCP and predictive abstractionThe loss when the extension point you predicted turns out to be wrong. A wrong abstraction costs more than duplication
04LSP and contractsThe four items of precondition, postcondition, invariant, and history property. How far the type checker is actually looking
05ISP and structural typingThere are two motivations, and one of them depends on the language. In TypeScript you can satisfy it by narrowing a parameter type alone
06DIP, DI, and IoCThe three are separate concepts. Passing dependencies in from outside does not by itself invert anything
07Conflicts and the limits of the principlesJudgment calls where the principles pull against each other, and modern criticism of SOLID itself

Who this is for

  • People who know the SOLID definitions and are unsure how far to apply them to real code
  • People who have had the experience of "I wrote it by the book and it got harder to read"
  • People who review designs and want to put the basis for their comments into words

Prerequisites

LevelKnowledgeNotes
RequiredThe basics of classes and interfacesYou can check these in Clean Code Guide — Classes and Interfaces
RequiredThe definitions of the five SOLID principlesThe content of Clean Code Guide — SOLID Principles is taken as given
RecommendedThe basics of TypeScript typesThe code examples are TypeScript. The principles themselves are language-agnostic

What this series does not cover

  • An introductory explanation of the five principles — covered by Clean Code Guide — SOLID Principles
  • A catalog-style explanation of design patterns — patterns come up as far as they are needed to explain a principle, but the structure of and choice between individual patterns is out of scope
  • The internals of a specific framework — framework-specific topics such as how a DI container works are not covered