Solve The Real Problem

Discussions about professional software development with a focus on building real, solid, performing, reliable, monitorable large-scale online services in asynchronous C++. You know, good solid breakfast food.

Tuesday, January 23, 2007

On Simplicity

I had a discussion today with someone about software, and when I was trying to describe some of the key qualities I seek when building systems, I listed off the usual set of descriptors: scalable, fault-tolerant, simple, monitorable, maintainable, and so on. What surprised me was that the other person picked right up on the word "simple". As soon as I said "simple", they understood exactly what I was getting at, and they could see the kinds of benefits that simplicity could have. The surprising parts were that they aren't a software expert by any means, and I almost didn't even include "simple" in the list.

Why was it an afterthought? Because, for me, it has become so obvious, so necessary that it almost literally goes without saying. Which is funny, because if I had to chose one word, and only one word, to describe what I aim for, "simple" would be it. I'm reminded of a quote I read in the official Bell Labs history:

"Cognitive engineering" is what [Joe] Condon called it, "...that the black box should be simple enough such that when you form the model of what's going on in the black box, that's in fact what is going on in the black box."

This is an interesting way to think about design. Through appropriate uses of abstraction, even well-designed complex systems can be see as a collection of simple "black boxes" that, at a high level, just do what you think they do. Their complexity comes out of the number of abstraction layers and the number of abstractions that interact throughout those layers, and not from within any of the individual abstractions. Any individual black box has a clear, simple function. It might need several inner black boxes in order to perform that function, but those again, are clear and simple. This self-similarity forms a very organized chaos, which, if you tried to view it all at once with all the walls of the boxes taken away, would be an incomprehensible mess. It is the power of abstraction, the power of the black box in turn enabled by the power of the well-defined interface that turns complexity into simplicity.

So, as a systems designers and builder, I will frequently be faced with a complex problem that needs solved. By identifying the individual "real problems" within the overall problem space, I am applying the abstraction tools to impose an order, piece by piece. Whether I do this top-down, bottom-up, or any which way, the point is that I start building the walls of the black boxes and start defining the interfaces between them at a variety of levels. I try to use as many existing boxes as I can (sometimes with renovations), and, in fact, my experience is such that this process itself exposes more opportunities to use the same kinds of boxes in different problem areas. If someone can look at the end result and see simplicity, then I have been successful in designing a flexible, trustable solution. That's when we know we've done well.