A philosophy of software design by John Ousterhout
Tags: architecture, software, books
Published: 2022-12-27 18:07:22

I recently came across this small (less than 200 pages) and clever book which I found very interesting.
With the aim to make you buy your own copy, I will tell you about this book, focusing mainly on the complexity concept.

[John Ousterhout](https://en.wikipedia.org/wiki/John_Ousterhout)  is a professor of Computer Science at Stanford University. He also invented [TCL](https://en.wikipedia.org/wiki/Tcl) a “high-level, general-purpose, interpreted, dynamic programming language” in 1988.

John decided to write this book because he found that the most demanding process in computer science is problem decomposition (that is how can I split a complex problem into smaller, manageable and developable parts?). Yet nobody teaches this skill: everybody builds on that, taking for granted that anybody can do that, as an innate feature.

The author thinks that designing skills are what separates a great programmer from average ones.

His mantra, emerging throughout his work, is: **reduce complexity**. 

Ousterhout is also humble; he knows very well that his book derives from his own opinions and that we might disagree with his view. He invites us then to take his suggestions with a grain of salt.
I found this very refreshing: there are a lot of books out there that provide us the real-truth, in every human field!

**Complexity is everything that makes it hard to understand and modify the software.**

Signs of complexity include:

- Change amplification: a supposed simple change requires a lot of updates in many different parts
- Cognitive loads: how much a developer needs to know to complete a task?
- Unknown unknowns: it is not clear what should be done in order to achieve our goal

The causes of complexity are either dependencies or obscurity.

We cannot really create a software system without adding some **dependencies**, but our job is to make it explicit and reduce their number to a minimum.

**Obscurity**, defined as anything that is not obvious or not consistent, is clearly subjective. So we cannot evaluate it by ourselves, we need code reviews.

We should understand that **complexity is an emergent quality**. It is something that accumulates by every little thing we skip to the next time. Every little thing that we leave unresolved will settle creating a layer of dust into our system. As the dust grows, our system becomes dirt. But when exactly it became dirt? You cannot tell the real moment: cleanness, as complexity, is a gradient. And it has no end!

That’s why there’s a chapter called “working code isn’t enough”. Tactical programming (that is ‘get those features as quickly as possible’) won’t work in the long run. This is how systems become complicated.

In order to avoid complexity, we always need to keep in mind the long-term structure of the system, an approach the author defines as **strategic programming**.

We seldom create software from scratch nowadays: instead, we are almost always updating existing code. So we should program in order to ease future code extensions: this will ease our future developments.

A software system is composed of different abstraction layers. 
Ideally, methods directly implementing the interface should be at the highest level of abstraction and make use of lower ones in order to achieve their goals. 
If we found ourselves up and down this lattice we might have a problem with class decomposition.
We might have a problem, for instance, when facing pass-through methods (from one class to another) if they contribute no new functionality. A dispatcher, for instance, is a pass-through method, but It has a reason to exists.
Decorators (as per the author’s point of view) add seldom new functionalities and usually, we can avoid them with other methodologies.
And how we can evict pass-through variables? Ousterhout suggests using a context object, an object which will contain all the needed pass-trough information without recurring to global state (which is, indeed, bad)... 

Ousterhout suggests investing about 10%-20% of the time planned on a task to produce better software design. This will make completing tasks 10%-20% slower, but only in the first runs: since once the complexity is reduced, we can take advantage of that. 

[Side note: This resembles the boy scout rule, isn’t it?]

One advice the author gives us is to try to design every system twice, trying to approach the problem from different standpoints. No one gets it right at the first try!

## Conclusion

In the whole book, the author provides many examples to make clear his point of view; it also gives programming advices besides complexity that are really worth reading, so I hope you'll get the book!