Problem Decomposition

Splitting a problem by responsibility rather than by folder name — and the single-responsibility idea stated as "a coherent reason to change" rather than "one thing".

Problem Decomposition
▶ lab

Split a problem into responsibilities and give each one an explicit interface. Splitting it into folders named after technical types is not decomposition — it is filing.

Q · A feature is too big to hold in one head. How do I split it so the pieces are genuinely easier than the whole?
Designing by Responsibility
▶ lab

Ask of every unit: what is this responsible for? If the answer needs the word "and" more than once, you have found the design problem before it found you.

Q · What question do I ask of a class, module or function to find out whether it is well designed?
Single Responsibility, Carefully

Not "a class does one thing" — that phrasing has no content. "A module should have one coherent reason to change" has some, and even then the hard cases are genuinely ambiguous.

Q · What does "single responsibility" actually mean, and how do I use it without shattering a codebase into pieces nobody can follow?
Separation of Concerns

Transport, business logic, persistence, formatting and infrastructure change for different reasons, so mixing them is expensive. Adding a layer for each of them anyway is a different and equally expensive mistake.

Q · Which concerns genuinely deserve to be separated, and how do I tell that apart from adding layers because separation sounds like a virtue?
Decomposition by Folder

The anti-lesson. Splitting by technical type puts every file of a kind together and every file of a feature apart, producing boundaries that no requirement respects.

Q · Why does a codebase organised into neat `controllers/`, `services/` and `models/` folders still make every change touch six files?
Finding Seams
▶ lab

Three probes locate where a boundary should go: follow the change, follow the invariant, follow the rate of change. All three are questions about evidence, not taste.

Q · I accept that boundaries should contain change. How do I find out where the boundary actually belongs, rather than guessing?
Over-Decomposition
▶ lab

Ten files that must all be read together are worse than one file that need not be. Splitting has a cost, it is paid by every future reader, and nothing about it is free.

Q · How do I tell a split that contains change from one that merely spreads it across more files?