While following the Tweets that sparked my last post, I read the following regarding software architecture as a set of design decisions:
Yes, these decisions shape–give form to–the system. But they also shape–set direction; constrain; bring integrity, consistency and unifying aesthetic to–the system. And, yes, the structure of the system encompasses decisions, so there is at least an overlap between these definitions, but the emphasis is shaded differently
The second sentence, particularly the word “constrain”, stood out to me. Architecturally significant decisions, while setting the path for an application’s evolution, can also eliminate alternate paths from consideration. Our decisions frequently close doors, some of which may be extremely difficult to re-open.
Later in her blog entry, Ruth notes that architecture expresses intent: “what” (functional requirements) and “how well” (quality of service requirements). In her words, “…the form should deliver and serve the system function(s) or capabilities, and it should be sustainable (so evolvable and, as pertinent, scalable, and so forth)”. She cautions, however that “…there will also be choices that are so subtle we didn’t even know we were making them”. This is particularly important, because “…deciding that something is architecturally significant means it is one more thing the architect (or architecture team) is going to need advocate and explain and defend and influence and coach and tend…nurturing and evolving the design in the context of organization needs, forces, personalities and more”. This applies to unconscious, unintended decisions as much as those that are made deliberately.
There is a common thread that runs through this post, “It worked in my head”, and “The Most Important Question”: care. Exercising due diligence to provide a sustainable architecture is the hallmark of an effective architect. Painting yourself into a corner when you had alternatives is the unforgivable sin.
In “What’s driving your architecture”, I cataloged a dozen different factors that drive architectural choices. The complexity inherent in considering and balancing these factors is a prime reason that I have no confidence in the concept of emergent architecture. It is difficult enough to evolve and maintain a cohesive, sustainable architecture of any real size when working with an architect/architecture team with a well articulated vision. To suggest that it will “just happen” as a result of individuals doing the “simplest thing that could possibly work” seems a bit Panglossian. As Charlie Alfred noted in a comment on “The Most Important Question”: “Decomposing a system into its parts can only tell you how they work together, but never why they work that way”. Without some unitary guidance, it’s unlikely that the “why” for the system as whole was actually adequately considered.
Another potential source of inadequate decision-making is deferring decisions for too long. Rebecca Wirfs-Brock, in “Agile Architecture Myths #2 Architecture Decisions Should Be Made At the Last Responsible Moment” made the case for just enough up front design thusly:
So what is it about forcing decision-making to be just-in-time at the last responsible moment that bugs me, the notorious non-planner? Well, one thing I’ve observed on complex projects is that it takes time to disseminate decisions. And decisions that initially appear to be localized (and not to impact others who are working in other areas) can and frequently do have ripple affects outside their initially perceived sphere of influence. And, sometimes, in the thick of development, it can be hard to consciously make any decisions whatsoever. How I’ve coded up something for one story may inadvertently dictate the preferred style for implementing future stories, even though it turns out to be wrongheaded. The last responsible moment mindset can at times lull me (erroneously) into thinking that I’ll always have time to change my mind if I need to.
Making decisions early that are going to have huge implications isn’t bad or always wasteful. Just be sure they are vetted and revisited if need be. Deferring decisions until you know more is OK, too. Just don’t dawdle or keep changing your mind. And don’t just make decisions only to eliminate alternatives, but make them to keep others from being delayed or bogged down waiting for you to get your act together. Remember you are collaborating with others. Delaying decisions may put others in a bind.
In a follow-up post, she buttresses this with scientific evidence from a study that found “…those who were exposed to stress of any kind tended to offer solutions before they considered all available alternatives”. This does not mean that the decisions made were automatically “bad”. However, neither would it follow that the decision made was optimal for the given context. Lots of “good enough” decisions can add up to failure if they do not cohere over the long term and are not revisited.
Care must also be taken not to rely too much on the ability to revisit and refactor. Rework to address changing circumstances and unforeseen issues is a necessary evil from the customer’s viewpoint. Rework that could have been avoided, however, is rightly seen as waste. A little extra work to ensure future flexibility can be easier justified than major revisions to accommodate something you should have known was on the horizon.