Not being sure of something is usually thought of as a problem. Kevlin Henney argues to the contrary.
No, I'm not talking about Heisenberg, his lack of certainty or what he may (or may not) have thought about Schrödinger and the virtual vivisection of his cat. I'm also not referring to Heisenbugs, those peculiar defects that seem to disappear or reappear somewhere unexpected when you rerun code in a different environment, such as under a debugger, on your machine (it worked on mine) or at the customer's site.
The principle is that, in software development, a lack of certainty about something can be part of the solution rather than part of the problem. This point of view can, to many, seem a little counterintuitive and more than a little disturbing. There is a strong tendency for humans to feel unsure about uncertainty, in two minds over ambiguity and a little wobbly with instability. Whether over technology choice, implementation options, requirements or schedule, uncertainty is normally seen as something you must either suppress or avoid. Of this many people appear, well, certain. That you should embrace it and use it to help determine schedule and design is not immediately obvious.
Does an iterative approach to development embrace uncertainty? It can do, but not the way that most practitioners justify or use iterations. Starting from a position of incomplete knowledge and gradually iterating through hypothesis, experiment and discovery towards – one would hope – working software addresses part of the question of moving from the unknown to the known. But this view of iterative development accommodates and seeks just to reduce uncertainty over time rather than genuinely embracing it and using it to drive everything from critical project and product decisions to the detail of code. It is a subtle but important distinction.
Uncertainty arises when you are aware that at some point a decision about something may need to be made, and it is not clear what the best option is, but it is clear that it could have a significant influence. This may relate to an implementation detail (list or lookup table?), a broader technical choice (off-the-shelf database or custom, in-memory data model?) or a customer decision based on market direction (blue pill or red pill?). The decision point may appear to be now, but now may not be the best time to commit one way or another, even though you want to make progress.
Lean thinking offers options thinking as part of its toolkit, the act of taking a decision to take a decision, deferring a decision to a later point. This is not a matter of hesitantly wavering over a decision; it is based on identifying the last responsible moment a decision can be made, one that balances maximum knowledge with maximum opportunity.
But uncertainty is not just a driver for the schedule: it influences code. When there is more than one way to do something, many developers take that as a cue that what they must do is choose one. They may find themselves debating the choices with a colleague. In such a situation, it turns out that the real challenge is actually not to choose one of them, but to restructure the code so it’s not as important which option is chosen. Add an object, an interface or a wrapper layer that reduces the significance of the actual choice. Then, should the decision need to be retaken, either because circumstances change or new information becomes available, the impact of change is diminished.
Uncertainty need not be unprincipled. Use it to help mark out the boundaries in a software system and loosen the coupling. Entertaining more than one option is not an act of indecision: it is a reflection of understanding, a way of uncovering possible areas of instability and seams of change in a software architecture. As Émile-Auguste Chartier noted, “ nothing is more dangerous than an idea, when you have but one idea ”.
(First published in NDC Magazine, June 2009)