Revealing hidden assumptions in estimation 19 Nov 2005
It is trivial to estimate a new feature as trivial. All too often, programmers and users both fall into this trap. A programmer says, “let’s just make it do X.” A user says on a forum, “its only Y, how hard can it be?”
Just and only are two of the most insidious words in the English language. They hide mountains of assumptions behind them, and blind the speaker to the realities of the situation. Even worse, the speaker is implicitly agreeing to be blindfolded, making it even more difficult for them to see the assumptions their words are masking.
“[It] would seem to be a trivial programming matter.”
“It would be a simple programming matter to implement.”
“There isn’t really any big technical hurdle unless they have poor table structure in their database.”
“Am I missing something here? Is there some technical hurdle that stands in the way of the addition of this feature.”
“And yet it’s not implemented, and you act as if you guys have no real desire to put it in.”
“I think they will add this feature when script.aculo.us supports nesting in it’s lists.”
The above quotes are among many from a thread on the Backpack forums where people were asking for multiple to-do lists per Backpack page. We have finally implemented this feature (as announced in this thread on the forums), but I wanted to talk a bit about the real work involved in implementing it, as opposed to the imaginary work assumed by the users quoted above.
Imaginary work is always easier to do than real work. It is much more attractive (being more quickly done) and once you see the imaginary work, it can be very difficult to identify the real work it masks. People estimating imaginary work often assume they have all the facts in hand when making their estimates, which assumption leads them to believe that there is no “big technical hurdle” preventing its implementation. The people quoted above, for example, made two very large assumptions. They assumed (without realizing it, I’m sure) that changing Backpack’s data model was trivial to do, and that the impact on the UI would be minimal.
The modifications to the data model—although straightforward to the theoretical model itself—were fairly time-intensive to actually implement. Consider even the task of migrating all of the existing data to the new model. There are hundreds of thousands of Backpack pages in the database, and millions of to-do items. Going from a page-centric model to a list-centric model involves a significant bit of work (creating tables, adding and changing records, adding and dropping indexes), all of which must be carefully tested to ensure we don’t corrupt our users’ data while giving them this new feature.
Even the data modifications were simple, though, compared to the user-interface issues. The browser is only one of four interfaces to Backpack, the other three being email, mobile, and the programmer API. It is far from sufficient to change the browser UI when adding new functionality. And in the case of multiple lists, we also needed to maintain backwards compatibility for the creation of list items via email and the API.
“Backwards compatibility” always adds complexity. Suddenly we have special cases. “A request to create an item should specify a list ID. If it does not, assume the list being operated on is the first list on a page. If the page has no lists, create a new list and add the item to that list.”
It isn’t just the implementation of the feature that is challenging. We need to augment out unit tests to make sure that the special cases are all covered. We need to make sure the new functionality is accessible to the user via the interfaces. If we decide not to make the functionality accessible via one or more of the interfaces at this time, we need to at least make sure the new functionality does not break the existing interface.
Keeping the UI clean can be a challenge sometimes. “Having multiple lists per page” implies the ability to create new lists, destroy existing lists, and rename lists. Also, to keep things consistent, we ought to be able to reorder the lists on a page. Each of these operations require additions and tweaks to the UI, as well as the addition of yet more unit tests to make sure the features are implemented correctly.
And don’t forget the CSS and Javascript tweaks that make it all look and run smoothly. In some cases, a new feature may require extensive refactoring of the Javascript code. In others, the feature may require changes to layout that break the existing CSS styling. (In this same vein, fussing is another task that is commonly underestimated, both in value and in difficulty.)
That’s not to say any of this was particularly difficult. Mostly, it was just tedious. It was time-consuming, and required a fair bit of attention to detail. But whether a task is particularly difficult or not, underestimating the time that task takes to do is always the easiest part, especially when you’ve got those self-inflicted blinders on that prevent you from seeing your assumptions.
Next time you find yourself thinking something ought to be simple to do—whether in a project of your own, or in someone else’s—pause for a moment. What assumptions are you missing? What real work are you overlooking because the imaginary work is so much more attractive?