Agile myth buster of the day: Nothing’s wrong with spending some time doing up-front design. In fact we almost always do it for anything bigger than a small class. We do it with our pair partner, or sometimes together with the whole team. It usually takes an hour or two, and often involves a whiteboard or some cards. It’s always followed shortly thereafter by converting the design to code. Every so often it creates a diagram we favor and squirrel away in the project docs directory.
So the problem with up-front design isn’t doing some of it, it’s in allowing the time you spent doing it and implementing it to marry you forever to that design. Knowing when to divorce your old design is an important skill.
Here’s how the trouble starts: developers recognize a shortcoming in a design decision made some time ago as they try to accommodate a new feature. Time is added to the iteration to accomodate the necessary refactoring. This refactoring doesn’t deliver features per se, so doesn’t produce a noticeable deliverable for the customer, or the new feature necessitating the redesign takes a seemingly large amount of time. The customer, or the project manager, question the need for the refactoring. The developers, who thought of the original design anyway, cave in to customer pressure or delude themselves into thinking the original design is acceptable, ignoring the smells in the code. Developers or customers think that because time was spent on the original design, project time and money have somehow been “wasted”. They imagine that keeping the original, now insufficient design, prevents this waste and preserves value.
In truth staying married to a design that no longer meets your needs, regardless of how much time was invested in creating and implementing it, will only slow the project and waste time and money in the long run. If feeling bad that your crystal ball didn’t accurately predict all aspects of the future prevents you from refactoring and moving on then you’re in effect saying that you won’t learn from your project experience, or let that knowledge be folded into the code. “Design is done, no more good ideas!”
So is this a failure of the agile emphasis on “just enough” design, or “design for today”? After all, if we could have seen this coming with more up-front design we could have avoided the original, insufficient design and saved time. (And if you knew what the stock market will look like in a few months your design abilities would be a moot point.)
I thought about this today as we came to grips with design decisions we made three months ago for a robot class that drives a car on a dynamometer. Back then our model was for a dumb robot. Now we’re seeing features that require more autonomy and smarts. It’ll take a day or so to refactor robot properly. That’ll mean we need to squeeze a feature out of this iteration. Our customer’s are smart and understand the value, so we don’t have that pressure. Is it too surprising that a decision we made very close to the project start, our point of maximum ignorance, hasn’t lasted through to the end? I don’t think so. The dumb thing would be to ignore the insights and vast amount of knowledge we’ve gained in three months and stay married to our first design. We’re calling the divorce lawyer tomorrow.

