The subsystems of a product are each developed in several stages:
This stage defines the functionality of the product. The func spec is developed, after proper attention to the requirements. The resulting func spec must satisfy the requirements.
This stage should include prototype code and implementations of certain core features, forerunners of the more extensive code to come in the skeleton development stage.
Our experience is that coming up with a good func spec is the riskiest part of a project schedule-wise, because it employs so much imagination and cross-department decision making. Our problem was that so much of the product direction depends on factors that won't be known until late in the development cycle. The best solution we've come up with is to form top-level decisions early and make them come true. Pick the lowest common denominator among possible feature lists in something the product will depend on. In practice it's not easy to do since some lowest common denominator decisions are unacceptable, so one has to take on some risk in order to guarantee the production of a uniquely valuable product.
Another alternative approach is to form a strategy along with contingency plans in case of direction change. But contingency plans take time to create, which slows development, which is deadly in a fast-moving industry. By aiming and developing as quickly as possible, one can finish a product and then do a corrected version as quickly as one would develop a single moving-target product.
Only when the func spec is completed can an accurate schedule be made for a product. Different levels of func spec completeness allow correspondly more accurate schedules. The schedule can be made by having the program architect list the programming tasks represented by each feature in the func spec. Since the func spec contains a complete list of product features, albeit from a different point of view that requires much cross-correlation and analysis to turn into a feature list, this procedure results in a complete list of programming tasks. With this list in hand, the architect and program manager can prioritize and schedule the project's completion.
Note that the schedule cannot be made before the func spec is available. The trick is to make a rough spec that allows creation of a rough schedule, without glossing over major aspects of the user experience design that will greatly affect the schedule. The dilemma is that the func spec must be of the most complete describe-every-detail variety to make a most-accurate schedule, but such a func spec can't be made in one big push. It must be grown over the course of the project, with limbs fleshed out as more user testing and experience with the product is accumulated. Attempts to overdefine at the start of the project inevitably fail as new ideas later bloom and are incorporated. So func spec creation is a balancing act, doing just what's needed at each point in time, and no more.
This stage implements a version of the product which includes something from each potentially complicated part of the func spec. That is, the skeleton version is runnable and gives a feel for the product but is is designed to help the developers to get a solid framework for the system, rather than to be something that customers will be able to use.
To say it another way, the func specs and rough architecture from the func spec stage will definitely have bugs, things that aren't fully thought through despite best efforts. The goal of the skeleton development stage is to work through those bugs by actually coding some part of each fuzzy aspect of the design.
When the skeleton is complete, the func spec bugs will have been worked out and the architecture and top level design of the program will be firmly in place. So the skeleton acts as a bug-fixing stage for the func spec as well as a filling-in stage for the architecture and design and the toughest core parts of the coding.
Note that the skeleton is not ready for customer use. Necessary features, from the user's point of view, may be missing. The focus was to work out sticky spots in the architecture, and if those necessary features weren't sticky spots, they won't have been done at this stage.
This stage produces the first version of the product that is at all usable by customers. It has a minimum useful feature set so that customers can actually get something done with the product. It is by no means the final product, as many very helpful features are put off until later stages, but it is the first version that can actually be used.
The important thing to do in defining what's to be a part of the minimum release is to ruthlessly prune anything not needed to convey the point of the product to the user. If ease of use is the point, the minimum must show how the whole product will be easy to use. Core features must be present, enough so that the feel of the product is apparent.
It's to be expected that the product will change, perhaps significantly, after the minimum is completed. This is, after all, the first stage where users can offer feedback that makes sense in the context of the product. The philosophy of the product may be set by this point, but many of the details involved in implementing that philosophy can be reworked.
When all the changes have been worked out, all the features deemed necessary implemented, and the quality of the code brought up to an appropriate level, the final product is done.
| || |
March 25, 1996: created.
April 22, 1996: func spec and schedules.
Copyright © 1996,
All Rights Reserved