Mon 23 February 2026

Review: A Philosophy of Software Design

Last year I read the book 'A Philosophy of Software Design' by Ousterhout. After finishing the book I wrote a review and reading it back I thought I should follow up with a reflection, the reflection is not yet written this is just the review.

The Review

The book offers an alternative perspective on existing approaches to software design in ways that are more pragmatic, with a strong focus on the core principle in software engineering; to tackle complexity.

Ousterhout clearly understands the power of abstraction as a tool for managing complexity and he applies this himself by creating his own metaphor for how software should be designed. He describes systems as having interfaces that should be shallow and implementations that should be deep. A simpler interface will provide less cognitive load than one with a larger surface area and if the implementation is deep it will provide significant power to the user.

Interestingly he also attempts to avoid jargon while describing things such as preferring to say "avoid duplication" instead of spelling out DRY. I believe he does this to allow the reader to grapple about how they are designing software instead of falling back on a adages like DRY as a core tenet without applying thought into what one is actually aiming to achieve. In other words I believe he wants the reader to make intentional choices when it comes to designing software.

Some of the example he uses are obvious to those that have experience reading code, most notably his sections on code comments, however I think his assertion that people don't write documentation upfront because they view is as "drudge work" is true.

He only starts mentioning cognitive leverage in concluding chapters of the book, I think it should be quite a core principle but perhaps a foundation is needed first to then understand how one can use leverage.

A lot of the book I agree with but I'd perhaps want to provide an alternative view on some of the areas he mentions.

The book makes a strong argument that we need to think more about software design than we are doing, I think there's also a balance to be made here. A good developer should be able to figure out if software should be done tactically or if it should be done strategically. Tactical coding does lead us to worst code in the long term and I've seen tactical more often than not, however I don't believe we should constantly be under strategic programming but as an industry and for early career developers we need more of it. Some software doesn't need design but that's an edge case and shouldn't ever be used as an excuse to avoid thinking through a problem.

In my view where developers lack the most thought and tend to create shallowest interfaces are when creating modules.

Shallow modules are a plague in the industry, I've seen very few examples where a developer has realised that modules are themselves an abstraction and a module's design should be considered. Too often we look at the method signature or class methods and believe this is where we create interfaces and abstraction. We must not forget the file or package is itself an abstraction and we should be thinking intentionally about its interface.

I enjoyed his emphasis on thinking "about different pieces of knowledge that are needed to carry out the tasks of your application". Finding the correct balance is a developer skill that can only improve when you consider and make intentional decisions about how you lay out your code, often avoided (and now offloaded) by engineers as it requires us to put in more effort with thinking.

One of the most important elements of software design is determining who needs to know what, and when

Page 43.

When solving a problem, it is far easier to rationalise and decide on your best course of action when that problem can fit in a paragraph. Isolating the relevant information in one space helps, having to go back and forth between pages or modules is a clear indication that the design has a flaw and my impression is that Ousterhout would agree with this. Further to this point, I believe an IDE can make finding all relevant parts of the code easier but doesn't address the core issue, and over reliance on the IDE will suppress issues and complexity creep.

TDD

I don't agree with his take on test-driven-development, in some cases it forces the developer to start thinking about the interface as a user. Writing the test gets you thinking about the module as a user of the module, since a simple interface would hopefully lead to simpler tests. Some of the key design flaws in an original design or even after the design has been done comes from actually using the module.

Leaving comments

I have come to realise that we have access to many tools that can be used in software design and focusing on using them to address complexity should be their main concern. Many of the examples with comments are in their usage, because we have access to comments doesn't mean we should use them for everything and we should be open to discovering more creative ways to leverage comments to tackle complexity.

Reading the code of others helps us discover interesting ways these tools may be utilised and helps us improve in these areas of software engineering.

One of the key points he makes is about determining the obviousness of the software which connects with how I've approached writing code and how I believe the design of software should be faced.

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.

Antoine de Saint-Exupéry

Socials
Friends
Subscribe