Valuing Ambiguity

One of the things I like about presenting live is that under pressure I think new thoughts. Puzzled looks can give me the energy to find a novel explanation. Excitement can spur me to dig deeper into explaining a topic than I have before.

My recent full-day Responsive Design tutorials in Seoul and Beijing gave me many such inspirational (or terrifying) moments. I had never put together a whole day’s worth of this material before. I didn’t know quite how to prioritize the topics, nor how best to explain them. My strategy was to take my best guess and be guided by feedback from the audience.

Late in the slide making process I added a slide on the values behind Responsive Design. At the last moment I added an item to the slide called “ambiguity”. I thought it was important to talk about the value of patience to a responsive designer. A toss-off item on a toss-off slide turned out to be the biggest surprise of the tutorial, a blink-their-eyes-and-sit-up-straight moment for many attendees.

Ambiguity

A design is ambiguous where it isn’t “right” but there are multiple ways of making it better. For example, an area of the design might have considerable duplication or the control flow might flow through elements that don’t add information to the computation. As the Design is an Island model explains, moving to a better design might lead in any of several directions.

Incremental design as described in XP takes a firm stance on such situations: eliminate the duplication or the excess complexity as soon as you see it. The responsive designer, however, takes a more nuanced approach.

Analogy: Go

In Go, the board is big enough that a lot can be happening at once. A corner can get crowded and messy, so that it isn’t clear who has the advantage. When faced with this situation, the inexperienced Go player will often push that area to a conclusion. It’s as if it is more important to be certain than to win, that the inexperienced player experiences anxiety when the situation isn’t clear.

The master Go player will push an area into a confused and ambiguous state and then start playing in another area of the board. The master isn’t bothered by ambiguity. He is confident that the situation will be resolved eventually, but sees no need to push any single part of the board to a premature conclusion.

The inexperienced player’s resolution of an ambiguous situation is premature because he doesn’t yet know how that area of the board will affect other areas of the board yet to be developed. It is a micro-optimization, reducing uncertainty and thus anxiety, where the master player simply doesn’t experience the anxiety and thus is content to wait for a macro-optimization opportunity.

It’s not that the master player doesn’t experience emotion during play. Rather, the master uses emotion productively, transforming it into focus, attention, and creativity, instead of needlessly dissipating it. The master combines a superior grasp of the board as a whole with the energy created by the ambiguity to create better play.

Example: Categories

For almost a decade people have been asking for a way to choose a subset of tests to run at runtime in JUnit. We have tried many different mechanisms–suite() methods, the Suite runner, filters, assumeThat()–to meet their needs. So far, none has had the right combination of binding time, expressivity, concision, and tool integration to satisfy the underlying need.

Categories are an area of ambiguity in JUnit. The current situation is messy, with several different mechanisms provided by us and many more provided by others. We have several examples of the intended use of categories–slow vs. fast tests, OS-specific tests–but no firm grasp on the underlying need to be met. Without understanding the need it would be foolish to rush into a design just because we’re worried about what people will think of us if we don’t. Designing half-heartedly (and half-brainedly) makes it that much more difficult to find a novel solution, perhaps one that eliminates the need for categories altogether (JUnit Max’s test prioritization was one such attempt).

We wait actively. We’ve started a category implementation three times that I can remember. We’ve tried a variety of experiments around the idea. We have the best category implementation so far started as part of the 4.8 release. In the meantime, people have been able to make do with the myriad of half-way solutions, ours and theirs.

Categories in JUnit are ambiguous because the current design is ugly and messy, but there are several possible ways to resolve it–either implement something that looks like explicit tagging of tests, suites, and classes or finding a completely different way to satisfy the same need addressed by categories.

Waiting is not Ignoring

There is a world of difference between waiting and simply ignoring a problem. The responsive designer nibbles around the edges of ambiguity, trying experiments, talking to users, looking for inspiration. When there’s nothing productive to be done to resolve the ambiguity, the responsive designer applies time instead of activity to the problem. Perhaps the problem just isn’t big enough yet. Perhaps the right idea just isn’t there. Perhaps working on another part of the system will spark the missing idea or eliminate the need for the ambiguous area entirely.

Another waiting strategy is to deliberately make the ambiguity more intense. Say you have a four layers of method invocation within an object and there’s something wrong with the way the methods are factored. Inline all the methods into one truly hideous method. Now all resolutions are equally distant. Try resolving the design several different ways. See which benefits the design and code most.

Resolution

Once the responsive designer finds an acceptable resolution, he pounces. The energy stored up during all those hours of frustration turn into action. On such days, thousands of lines of code can disappear. Often, a cascade of simplification begins, going far beyond the original intent of the resolution. These are glorious days for a designer. You have finally understood something valuable.

One of the tutorial attendees asked me how I know I have finally found an acceptable resolution. There are some intellectual cues: redundant code unifies, excess complexity vanishes, concepts that were hard to read in the code become blatantly obvious. My biggest clue, though, is my emotional state. If I start smiling and laughing, I’m on the right track.

Sometimes the whole resolution doesn’t fit into the current development rhythm. In such cases, the responsive designer does what he can, creates a parallel, and resolves to migrate gradually from the old design to the new. While this isn’t as much fun as finding and applying a new design all at once, at least the system is improving. This makes larger design improvements practical while maintaining the steady flow of features.

Conclusion

Following simplistic rules leads to designs that are hard to change when you learn better. Design when you know how to design (subject to producing a steady flow of features). If you know how to design before implementation, design then. If you know how to design immediately after implementation, design then. If you don’t know how to design, don’t. Use the energy created by aesthetic dissatisfaction to keep your mind working on the problem, but do something else valuable in the meantime.

5 Comments

Valuing Ambiguity « IdeA thinKING v3September 16th, 2009 at 4:23 pm

[...] [...]

PJSeptember 17th, 2009 at 5:59 am

To push the Go analogy a little further:

In go, the master will leave the ambiguous situation there but stay mindful of it so that adjacent situations may be used to influence the outcome in his favor.

Similarly, leaving some design ambiguous until something related shows up and then using that to help resolve the ambiguous design is often a good idea.

Esko LuontolaOctober 11th, 2009 at 12:42 am

It’s excellent and very valuable that you are putting into words the way that you’re doing design.

Already with your four design strategies (in the Responsive Design presentation at InfoQ), I could see the same things in the way that I’m also doing design, but I had never thought about it. But now that it has been put into words, it can help me to be more clear about how to do design and what alternative strategies there are to solve a situation.

Also, now as I read about ambiguity, it brings similar thoughts into my mind. I’ve experienced such moments where a messy situation resolved and made way for a better design, after I had been unconsciously ambiguous. But after reading this I can be consciously ambiguous, possibly leading into better designs.

Thanks for a good article. :)

Michael HungerOctober 20th, 2009 at 3:43 pm

But the responsive designer must have mastered design already? Most software developers that I know are hopelessly overwhelmed with ambiguous situations, the don’t know how to move at all and get stuck and paralysed.

I also feel the happiness and joy when an ambiguous design situation resolves. It is always like pieces of a puzzle falling into the right places where they belong and revealing an hidden painting.

I always thought about a virtual inline plugin that i can point to a method and say – inline all calls and (method) objects virtually up to a depth of x. And the use this virtual view to guide understanding, decisions etc.

KentBeckOctober 20th, 2009 at 5:05 pm

I think I’d like to use such a tool. It would have to be fast–I’d want to be able to use the scroll wheel, for example, to inline deeper and shallower at a couple of frames/second.

Leave a comment

Your comment