A Philosophy of Software Design, in detail
John Ousterhout's central claim in this book is that the greatest limitation in software development is our ability to manage complexity, and that almost every problem in large systems can be traced back to complexity that was unnecessary and could have been prevented. Ousterhout is a computer science professor at Stanford with decades of experience building systems software — he created the Tcl scripting language and the Raft consensus algorithm — and the book reads like an attempt to make explicit the design intuitions he has developed over that career.
The book's organizing concept is the distinction between deep and shallow modules. A deep module has a simple interface that hides a large amount of functionality — a file system call that lets you read a file in one line, regardless of the physical complexity beneath. A shallow module has nearly as complex an interface as its implementation, which means it doesn't do much to reduce the cognitive load of using it. Ousterhout argues that most complexity in systems comes from shallow modules, from leaking implementation details through interfaces, and from incremental design decisions that each seemed reasonable but together made the system harder to understand.
The second major thread is what Ousterhout calls "tactical versus strategic programming." Tactical programmers optimize for getting things working quickly. Strategic programmers invest in clean design even when it slows them down in the short term, because they know that complexity compounds. He argues that the investment is worth it — that the time spent thinking carefully about interfaces pays back many times over. This is easy to say and harder to institutionalize, because most software development environments reward shipping, not tidiness.
The book is compact at around 200 pages. Some reviewers have pushed back on specific prescriptions — particularly the advice to prefer fewer and longer comments rather than many short ones, which runs against some established conventions. And Ousterhout is unabashedly prescriptive: he has opinions, and he states them as principles. Readers who want a balanced survey of design approaches will be frustrated. But for developers trying to articulate why some code feels clean and some doesn't, and how to improve deliberately, the book provides a vocabulary and a framework that is hard to find elsewhere at this level of concision.
The big ideas
- 1.
Complexity is the root cause of most software failures. Managing it is the central task of software design, not a side concern.
- 2.
Deep modules have simple interfaces that hide a large implementation. Shallow modules expose nearly as much complexity as they contain, providing little abstraction value.
- 3.
Information hiding is the most powerful technique for reducing complexity. If a module knows less about other modules, changes are less likely to cascade.