This past week I've been reading "A Philosophy of Software Design" by John Ousterhout. I picked up the book after watching his talk on YouTube[1] that gives a general overview of the themes. The ebook was only a few quid and whilst its not super long its still great value for money. Probably the best serious tech book I've read to date, although not as fun as Ed Mastery by Michael W Lucas[2].
The main idea that Ousterhout argues is that good software design is not just about writing code that works, but also about creating code that is easy to understand, maintain, and modify over time. He has various pointers towards good design and red flags to identify bad design, but there are really two key points that I walk away with. First, the importance of thinking strategically rather than tactically, and second how the value of abstractions comes in the size of the ratio between their interface and their implementation.
Ousterhout defines thinking tactically as only thinking about the task at hand to solve the immediate bug or implement a particular feature, whereas thinking strategically is implementing that same change but in the wider context of the design of the whole system. It's an interesting conceptual difference that I will be sure to keep in mind when I'm working on changes to systems, but also a variable to be dialed up and down based on other business priorities. He seems to thinking that working tactically is never a good idea, and I'm not sure I wholeheatedly agree, but at the very least its a distinction that will nodoubt prove to be useful to consider.
The other main concept that Ousterhout explores in the book is the idea of abstraction. He argues that the best abstractions have a high ratio between the size of their interface and the size of their implementation, although he doesn't use such words instead relying on a geometic metaphor. Ultimately, the point he was getting at is that the abstractions that offer up the greatest value to the software system are those that have a small interface compared to their implementation. That isn't to say that interfaces should be no larger than a particular size, or that implementations should be no smaller than a particular size, but that the difference between the two should be as high as possible. Again, I think this is a useful rule-of-thumb that I'll be sure to keep in mind when evaluating different designs and approaches to a problem.
Overall, the book is a good read. Some of the examples are a bit dated and its clear that Ousterhout comes from an era when "real" software was written in C++ or Java -- there's no mention of functional design patterns, structural typing, or complexity in user interfaces which I think is a real shame. However, despite that there are some really insightful gems and I'd highly recommend it to anyone who works in any role relating to the development of software.
Last Updated: 2023-03-25
[1] :: A Philosophy of Software Design | John Ousterhout | Talks at Google