Reading "A Philosophy of Software Design"
Tags: softwaredesign
Published: 2024-04-19 16:20:49

I recently read "A Philosophy of Software Design," highly praised on my favorite Japanese podcast [e34.fm](https://e34.fm/). The first edition was published in 2018, and I read the second edition released in 2021.

## What kind of book is it?

The theme of the book is the complexity of software. Complexity is defined as something that makes it difficult to understand or modify a system. Symptoms of complexity include simple changes forcing many code modifications, increased cognitive load (as mentioned in ["Team Topologies"](https://teamtopologies.com/)), and most critically, the occurrence of "unknown unknowns." These unknown unknowns are troublesome because they can easily lead to the introduction of bugs, but by definition, their existence cannot be noticed.

The book introduces various design principles to reduce such complexity. Although it may seem like a catalog of design principles, the development of the discussion is systematic, and it has the impression of a book written by a researcher.

## Memorable sections
### Deep Modules and Shallow Modules
This is a frequently mentioned part of the book, but it was refreshing to talk about modules in terms of Deep/Shallow. The book argues that Deep modules are better. This distinction appears in Chapter 4, but it is repeatedly mentioned in subsequent chapters as a framework (e.g., "doing this will make the module deeper").

```
---------------------------------
|       | Interface | Functionality |
---------------------------------
| Deep  | Few       | Many          |
---------------------------------
| Shallow | Many   | Few           |
---------------------------------

```
※ The term "many interfaces" refers to the number of methods or many arguments for a given method.

### General-purpose and Special-purpose
This axis appears around Chapter 6, advocating for designing software that is somewhat more general-purpose than just meeting immediate needs.
Related to this axis, the advice to consider whether a process (code) is general-purpose or special-purpose and to ensure they do not mix, and the advice to remove special-purpose processes from the critical path in the chapter on performance (Chapter 20) were memorable.

### About comments
It's often said that code shouldn't require comments, but in this book, the author discusses what kind of comments are good, assuming there are things that can only be done with comments.

Personally, I found the discussion about comments to be full of useful advice, but what stood out most was the distinction between comments explaining details more than the code or comments explaining more abstract concepts than the code. It's often said not to write comments that merely repeat the code, but considering the degree of detail and which direction to lean toward when writing comments seems very helpful.

Also, it was memorable that the book suggested writing comments first, as a means of design, rather than later. If you try to write comments later, they may end up repeating the implementation or not being written at all. By writing comments first, they become part of the design activity, making it more enjoyable and leading to design improvements by considering abstractions.

### "Increments should be abstractions, not features"
In Chapter 19, the author discusses object-oriented programming (especially inheritance), Agile development, unit testing, test-driven development, design patterns, and getters/setters.

There were many familiar stories, but it was striking to find the statement "the increments of development should be abstractions, not features" in the discussion on Agile development. When doing incremental development, how to think about design is a major topic, and this was the first time I saw advice in this form. In the following text, it says, "When you realize the need for abstraction, don't take time to create it bit by bit; design it all at once." Although this is still based on "when you realize the need," the direction of highlighting abstraction as the main focus in the development unit is quite convincing.

## Regarding the overall stance
I've introduced several memorable points above. Although there were many individual pieces of advice that made me think, "I see, that's an interesting way of thinking," overall, I was left with a strong impression that the style was quite different from what I've been accustomed to so far.