All software projects begin with "big upfront planning," even when the participants pride themselves on agile, iterative development. Upfront planning visualizes a best product in the absence of surprises. This exercise is useful so long as everyone agrees that a final product could never be built in such a form, without accepting great inefficiency. External requirements will change. Code implications will surprise everyone. Opportunities for cleverness will present themselves. We already agree we will need to iterate and update our plan as often as necessary.
In any case, we still make lists of "A features" with top priority for the product and its marketing plan. We do our best to keep the scope doable. Human nature and Parkinson's Law determine that the list is just enough to fill the available time, barring unreasonably bad luck.
Next, we try to put these features in a certain order for implementation. There are some easy (but wrong) ways to order these features. Perhaps we follow the order of a workflow: the user needs to complete step A before beginning step B. Perhaps the schedule will balance the load between different developers and teams. Maybe code dependencies determine that some features should be done before others. Is this sort of scheduling any different from a staged waterfall with milestones? Could we reformat the plans for each iteration and call it a Gantt chart?
The problem is that all such features, whatever their order for implementation, appear equally important to a developer. All look critically important to the final functionality. Marketing has agreed that this vision is a compelling product. Everyone has signed off that the list is doable.
Developers are prepared to make a heroic effort to check off every feature on that list. All features will be implemented, after a fashion. But will those features integrate well? Is it possible the requirements of one feature will interfere with the implementation of another? Will features share what they have in common and interact appropriately? Everyone expects these implicit features to be implemented. Implicit features are too numerous to list or even to anticipate.
Inevitably, some features are in serious danger. Products always have an inflexible deadline and inflexible resources; only features can adjust. Some features, explicit or implicit, will not get done. How do we guarantee that the missing features are the right ones? How do we avoid a broken product?
Instead, try this exercise. Divide your "A" features into two halves. If you had only half the time, could you take half the features and make a product out of it? It might not be a great product anymore, but there should be someone who would would find it useful. It would support a useful workflow and contain nothing unnecessary to that workflow. Is this the half of your features that you planned to implement first? There is a good chance it is not. And yet, this sort of prioritization is fundamental to agile planning.
Now try making a plan with one quarter of your features. Try very hard to imagine a self-contained product that you could complete in one quarter of the time. You actually want to give this product to a customer and have him solve a useful problem with it. He should not see features stubbed out "to be implemented later." So far as he knows, he may never get an upgrade, but he should still find this release useful for something. Try to design that product. If your development plan has a year allocated, then spend your first three months building this thing.
This first-quarter product may even need some features that are not included in your final product. That is okay. Put them in for a while and take them out again later if necessary. It is more important to add features to a product that already makes internal sense. As you add a feature, it must be reconciled and integrated properly with all existing features. Adding features to a broken product may result in contradictions that can never be resolved.
If your product is already broken, then fix it first. Remove existing features if necessary, and add them back later, when and if you needed them. Remove dead code ruthlessly. If you ignore your implicit features of integration, then you are facing a stabilization period longer than your original development.
Once you are able to design a complete product for the first quarter of your year, you will be able to design a product for the first three weeks of that quarter. Just divide the features by four one more time.
Marketing may have to adjust their habits somewhat, just as developers are expected to adjust. A specific list of features can not go out a year in advance. Promotional materials must concentrate instead on problems that the user can solve with this product. To compensate, no one must make an all-or-nothing bet on 100% success. We should have a viable mini-product guaranteed well before the final release. Progress should be much more visible and testable, and thus easier to predict. We can act on feedback from customers much earlier.
Some Agile processes such as Scrum deliberately focus on product planning and assume appropriate technical practices will be adopted as well. These practices include test-driven development, continuous integration, joint code ownership, and refactoring to remove complexity. Internal experts or actual customers need to use the code and guide the developers. When you want to have a complete functioning product at all times, you see why these practices are necessary.
Bill Harlan, February 2009.
Return to parent directory.