Library Discover Ideas My library Paths Compare Shelves Collections Method
A Philosophy of Software DesignJohn OusterhoutCover of A Philosophy of Software Design by John Ousterhout
3 min read

Technology & AI

A Philosophy of Software Design

John Ousterhout

John Ousterhout's short book arguing that the central problem in software is complexity, that complexity accumulates through small decisions, and that the standard advice about small functions often makes it worse.

First published
2018
Publisher
Dpunkt.Verlag GmbH
Pages
193
Level
Core
ISBN-13
9781732102217
softwaredesigncomplexity

Record checked against

Only one source carried a publication date for this work, so the year is uncorroborated.

Catalogue note

Reads as
TechnicalAssumes and builds craft knowledge.
Level
Core / BuildingAssumes general familiarity with the subject.
Approach
Applied
Written for
Engineers, Readers with some grounding
Your shelf

Saved in this browser only — no account, nothing sent anywhere. My library

Read this if

  • You build software and want the ideas under the tools.
  • You care why some things are obvious to use and others are not.
  • You keep fixing symptoms and want to see the structure producing them.
  • You work in this area and want depth rather than an overview.
  • You know roughly how the subject works and want the fuller account.
01

Complexity as the subject

His definition is operational: complexity is anything about the structure of a system that makes it hard to understand or modify.

His three symptoms are the useful part — change amplification, where a simple change requires edits in many places; cognitive load, the amount a developer must know to make a change; and unknown unknowns, where it is not obvious what must be modified. The third is the worst because there is no way to discover it before being wrong.

Unknown unknowns are the worst kind of complexity, because nothing tells you what you needed to know.

Devmark’s reading — not a quotation from the book
02

Deep versus shallow modules

His central concept. A module's value is the ratio of the functionality it provides to the complexity of its interface. A deep module offers a simple interface over substantial functionality; a shallow one has an interface nearly as complex as its implementation.

His argument is that shallow modules add cost without benefit, because the interface must be learned and the implementation is not hidden by it.

03

The direct argument with Clean Code

Ousterhout states explicitly that he disagrees with the advice to make functions as small as possible, and the book is partly a response to it.

His position is that decomposing aggressively produces many shallow modules, that the resulting indirection is itself complexity, and that a developer following a single operation through a dozen tiny methods is worse off than reading one longer coherent function. The disagreement is genuine and both positions have serious practitioners.

04

Information hiding and leakage

His treatment of what a module should conceal, and of the ways design decisions leak across boundaries — including temporal decomposition, where code is structured by the order operations happen rather than by what knowledge they need.

His observation that temporal decomposition is a common and rarely recognised source of leakage is one of the book's more original contributions.

05

Different layer, different abstraction

His rule against pass-through methods and pass-through variables: if adjacent layers have similar abstractions, the layering is adding indirection without adding anything.

The diagnostic is simple and catches a great deal of unnecessary structure in real codebases, particularly in systems built by applying architectural patterns uniformly.

06

Define errors out of existence

His most contrarian chapter. Rather than handling every exceptional case, redefine the interface so the case is not exceptional — his example is a delete operation that succeeds whether or not the item existed.

His argument is that exception handling is a major source of complexity, and that much of it exists because an interface was designed to make ordinary situations into errors.

Much error-handling complexity exists because an interface turned an ordinary situation into an exception.

Devmark’s reading — not a quotation from the book
07

Comments as design

His position on comments is the opposite of Clean Code's: comments should describe things the code cannot, and the act of writing them is a design technique because an interface that is hard to describe is badly designed.

His comments-first discipline — write the interface comment before the implementation — is the concrete practice, and it uses documentation as a design test rather than as an afterthought.

08

Strategic versus tactical programming

His framing of the underlying attitude: tactical programming optimises for getting the current feature working, strategic programming invests a small proportion of time in structure that keeps future changes cheap.

His estimate of ten to twenty per cent investment is arbitrary, as he acknowledges, but the framing — that complexity accumulates through individually reasonable tactical decisions — is accurate and useful.

09

Where it is limited

It is short, opinionated, and based on the author's experience teaching a software design course and building systems, with no evidence beyond that.

The examples are also drawn from systems programming and from student projects, and readers working on web applications or data pipelines will have to translate more than the book acknowledges.

10

How to read it alongside Clean Code

The honest position is that both are practitioner opinion, that they genuinely disagree, and that the disagreement is about a real trade-off rather than one of them being wrong.

Read both and hold the tension. Martin is better on naming, tests and professional responsibility; Ousterhout is better on modularity, interfaces and the costs of over-decomposition.

—

What to take away

  1. 01Deep modules, simple interfacesA module's value is functionality divided by interface complexity, which makes shallow ones pure cost.
  2. 02Over-decomposition is itself complexityFollowing one operation through a dozen tiny methods is worse than reading one coherent function.
  3. 03Temporal decomposition leaksStructuring code by the order things happen rather than by what knowledge they need is a common hidden cost.
  4. 04Design errors out of the interfaceA great deal of exception handling exists because the interface made an ordinary case exceptional.
  5. 05Write the comment firstAn interface that is hard to describe is badly designed, which makes documentation a design test.

Reading journey

A route through this idea

This book is not on a curated path, so the route below is derived from the catalogue: what comes before it, what goes further, and what approaches the same ground differently.

  1. Start hereAlgorithms to Live ByComputing, and it assumes less before you start.
  2. You are hereA Philosophy of Software Design
  3. Go deeperRefactoringSame ground — Computing and Design — and it assumes more of you.
  4. A different angleThe DevOps HandbookAlso about Computing, but it reads as reference where that one is technical.
  5. Somewhere else entirelyThe Manager's PathManagement and Computing travel together in this library, and this comes at it from the other side.

Nearby on the shelves

Related reading

↑↓ to move↵ to openesc to close