Author: John Ousterhout · Published: 2018 · Genre: Software Engineering, Programming
The biggest strength of A Philosophy of Software Design is a single, useful lens: design is about reducing complexity, and the best tool for that is the “deep” module, which hides a lot of functionality behind a simple interface. Its biggest weakness is thin evidence and narrow scope. Many examples come from student projects and the author’s own systems, and testing, concurrency and large-scale architecture get little attention. Any developer past their first year should read it, especially one raised on Clean Code.

The core ideas
Ousterhout, a Stanford computer science professor and the creator of the Tcl scripting language, built the book on a software design course he teaches, in which students write and then revise substantial projects.
- Complexity is the enemy. He defines it as anything about a system’s structure that makes it hard to understand and modify. Its symptoms are change amplification, where a simple change needs edits in many places, cognitive load and unknown unknowns. Its causes are dependencies and obscurity.
- Strategic, not tactical, programming. Tactical programmers ship each feature as fast as possible and pile up complexity; the extreme case is the “tactical tornado”. Strategic programmers invest continuously in design, and he suggests spending about 10 to 20 percent of development time on it.
- Deep modules. A module’s value is the functionality it provides minus the cost of its interface. Unix file I/O, with five basic calls (open, read, write, lseek and close), hides enormous complexity. Java’s classic file reading, which needs separate objects for the file stream, buffering and object deserialization, is his example of shallow classes, or “classitis”.
- Hide information and pull complexity down. Avoid information leakage, such as two classes that both depend on a file format. Structuring code around the order in which things happen, which he calls temporal decomposition, is a common cause. A module should absorb complexity rather than push it onto every caller.
- Define errors out of existence. Design APIs so fewer exceptional cases exist. He argues Java’s substring method could clamp out-of-range indexes instead of throwing, and regrets making Tcl’s unset command raise an error when the variable doesn’t exist.
What’s great
- Useful vocabulary. Deep and shallow modules, information leakage, pass-through methods and “design it twice” give teams precise words for design reviews. Each chapter adds warning signs to a summary list of red flags at the end.
- A needed counterweight. Ousterhout argues against splitting code into ever-smaller methods and against treating comments as failures. Good comments describe what isn’t obvious from the code, such as an interface’s contract or the reason for a decision, and he recommends writing them first as a design tool. The 2021 second edition adds explicit comparisons with Clean Code, and his 2024 to 2025 written debate with Robert Martin makes a good companion read.
- Brevity. It is short enough to read in a weekend, and every chapter earns its place.
What’s weak
The case is built on experience and classroom observation, not data, and the examples come largely from Ousterhout’s own projects and student assignments rather than large production systems.
Testing is a real gap. He dismisses test-driven development as too tactical, focused on getting features working rather than on finding the best design, and says little about how testability shapes good architecture, a gap reviewers such as Gergely Orosz have pointed out. Distributed systems, concurrency and functional programming barely appear, and his skepticism of event-driven code will seem harsh to anyone building modern services. Some advice, such as making modules “somewhat general-purpose”, takes judgment the book can’t fully supply.
Who should read it
Every developer past their first year, and especially tech leads who review designs. Read the 2021 second edition, and read it after Clean Code to see the other side of the argument.
Rating: 4.5/5
Image credits — Featured image: cover image via Open Library; cover design © the publisher, shown for review purposes. In-article images: Photo by Jakub Żerdzicki on Unsplash.


