Let’s imagine an ideal scenario for software development.
In this scenario, there are some users who have real needs that you can identify. Further, some of these users are paying customers who will gladly give you money if you can deliver value to them. You can express their needs as a set of criteria to be satisfied, and these criteria can be measured. Your customers bring you their business because: not only do you promise to identify what they want and build them a solution, you also promise to deliver a solution quickly.
The flow of information is something like:
latent demand -> characterized demand -> value-adding design -> production -> deployed solution
…and your goal is to have smooth and continuous flow through this process, gently accelerating for all eternity. The scope of the demand you can address and the supply you can deliver will continue to grow as long as your own capability continues to grow (remember that we’re talking about an ideal scenario!).
That is only a very high level description. How might a detailed process to realize such a system look? Imagining in detail how our ideal scenario might work may also give us some ideas for what might be possible in real life (in TRIZ, this practice is called the Ideal Final Result).
As information flows through the system, we must have some representation of it:
properties that we can observe and measure about customer utility
-> properties that we can observe and measure about the product
-> functions that the product will perform
-> mechanisms that realize the functions that the product will perform
-> processes that produce the mechanisms that...
what does the user want?
-> what will the product do?
-> how will the product do it?
-> how will we build the product?
There are many such representations, but let’s use:
- use case: a description of how the product will be used, in the context of the user
- functional requirement: an operational definition of what the product will do
- design parameter: an operational definition of how the product will implement a functional requirement
- constraint: some limitation on what design parameters may be chosen
- process variable: an operational definition of how a design parameter will be produced
Because we always want to deliver new value quickly, we want to limit the amount of work that we take on at one time. The smallest amount means one work request. But one of what? Since we are value-oriented, we will pick use cases, since that speaks directly in user terms.
A use case describes the value that the product delivers to the user, roughly by telling a story about how the product will be used. A use case is a structured story, and may make reference to, or be composed of other use cases. A use case will also make reference to functional requirements, as a description of role of the product in the user’s story.
A composite use case might be large, so we will decompose new large use cases until they no longer contain or reference other use cases. Such an atomic use case is then a candidate to schedule for development. A goal for our descriptions of atomic use cases is that they should all be of a similar size. A use case should be testable and traceable to customer satisfaction criteria. A use case should say as much as possible about the user’s needs, expectations, and goals, and as little as possible about the design of the product. For convenience, let’s call such an atomic use case a feature. A feature is the simplest practical expression of: what does the user want?
So our system (so far) consists of a process for identifying and describing features, and then scheduling them, one at a time, for further development. The old (and broken) way of development might accumulate a long list of such features, and then give them to somebody to analyze to produce another long list enumerating what will the product do? Which in turn would be given to somebody else to design, and so on.
But that’s not what we will do. As soon as we identify any new feature, we immediately enumerate a short list describing what will the product do? Then we will get right to work on a corresponding list describing how will the product do it? Then we immediately produce a description of how will we build the product? Then we build it.
In other words, we practice depth-first design.
Now, it takes a lot of expertise to design a product of any significance, so a team of experts will somehow have to work together and coordinate with one another to make all of this happen without tripping over one another’s feet. It’s one thing to say that we’re going to deliver one feature at a time, but how, exactly are we going to do that?
And that question is precisely what makes this story interesting…