Use uncertainty as a driver
People often think that most important thing about the presence of two options is to make a choice. In design (software or otherwise), it is not. The presence of two options is an indicator that you need to consider uncertainty in the design. Use the uncertainty as a driver to determine where you can defer commitment to details and where you can reduce the significance of design decisions. If you hardwire the first thing that comes to mind, you're more likely to be stuck with it. The incidental decision has been made significant and the softness of the software has been hardened.
There are many definitions of architecture. One of the simplest and most constructive comes from Grady Booch: "All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change." What follows from this is that an effective architecture is one that generally reduces the significance of design decisions. A system may be subject to frequent change, with certain design decisions being revisited. Of itself this need not be a problem, but it becomes a problem if retaking these design decisions involves significant rather than under-the-radar changes. Without paying close attention to the partitioning, incidental decisions that should be minor escalate into architectural decisions that are difficult to shift.
Uncertainty and change can amplify the significance of design decisions. When a design decision can reasonably go one of two ways, an architect needs to take a step back. Instead of trying to decide between option A and option B, the question becomes "How do I design so that the choice between A and B is less significant?" The most interesting thing is not the actual choice between A and B, but the fact that there is a choice between A and B and it is not immediately obvious how to chose.
It is not always so obvious that this is the situation, and sometimes an architect needs to go in circles before becoming dizzy and recognizing the dichotomy. Standing at whiteboard (energetically) debating options with a colleague? Umming and ahhing in front of some code, deadlocked over whether to try one implementation or another? A new requirement or a clarification of a requirement has cast doubt on the wisdom of a current implementation, but it's not entirely obvious that the alternatives are any better? Vexing over docs for two different libraries or uses of a library that appear to fulfill the same objective? That's uncertainty. Take a step back. What separation or encapsulation would isolate that decision from the code that ultimately depends on it? Extra privacy on a class, dependency inversion through an interface, an extra level of indirection through an adaptor, an platform isolation layer?
This work is licensed under a Creative Commons Attribution 3
Back to 97 Things Every Software Architect Should Know home page