So I have made my feelings regarding functional specs pretty clear already. It’s clear to me, and a lot of other folks, that prototyping can be a very powerful way to capture requirements. What I have been thinking more about lately is, “What is the best way to do that?”
While there probably is no single right answer to that question, I have been learning a lot so far. Here’s where I’m at.
In rapid prototyping, interactive prototypes are developed that can be quickly changed according to the feedback received from colleagues, stakeholders or users as they work with the prototype to accomplish specific tasks.
Although prototyping for manufacturing and for hardware may be different, rapid prototyping as used within software engineering is closely associated with the user interface.
Rapid prototyping is about starting from the user interface and customer experience and then building ‘down’ from there. (I think of ‘down’ as the direction we go when we code.) The more traditional process of starting from the abstract (specs, charts, documentation, etc.), coding a skeleton app, and then applying a user interface just seems counter-intuitive.
With rapid prototyping, the interface becomes a “living requirements document” and provides a way of identifying usability issues at the outset. Unlike ‘fossilized’ product documents, prototypes provide a clear picture of what’s supposed to happen, leaving nothing to mistaken impressions.
Todd Zaki Warfel, author of the book Prototyping: A Practitioner’s Guide points out:
Prototyping is a rapid, iterative process. It’s a process for exploring ideas, failing often, and learning quickly. If you’re focused on creating production-level code, you start to lose some of the value of rapid iteration…On the other hand, if you can produce reusable source code with very little or no additional effort, then your prototyping tool has the added value of [saving] development time.
There are two basic approaches to design testing (and thus prototyping):
To me, the formative approach is the best way to go in a lean environment. Test early and test through various iterations to make the final product the best it can be.
As I’ve said before, while every single corner case need not be designed, the major use cases and features should be fleshed out and prototyped.
There are several different types of prototypes including full, horizontal and vertical, high fidelity and low fidelity, chauffeured and Wizard of Oz prototypes.
The beauty of a high-fidelity prototype is that it provides users and stakeholders with a realistic sense of the user experience of the product, and, when well executed, leaves very little room for imagination.
High-fidelity, to me, means that the interface is clickable, but that the backend is not necessarily functional. In my mind, there are few (if any) better ways to communicate the needs to an engineer than to show them precisely how the application is supposed to behave. They can actually foresee some of the challenges ahead of them, be more thoughtful about the architecture and are likely to increase their velocity as well.
Some practitioners of rapid prototyping believe you should just throw out the prototype when you’re done with it. Evolutionary prototyping allows for reuse of many of the previous prototype iteration elements without waste.
High-fidelity, evolutionary prototyping makes a lot of sense in a lean environment. The prototype being tested leaves little to interpretation, the process is iterative, and successive testing molds the product into its final, most useful form. To me, it harmonizes well with the first of Toyota’s 6 simple Kanban rules: “Do not send defective products to the subsequent process.”
All of the methods of rapid prototyping have a lot of merit. If you are doing any type of rapid prototyping in the first place, you are a step ahead. That said, I am a very big fan of lean thinking. I really dislike waste. So the methods that are most interesting to me are the ones that involve ‘throwing away’ nothing. For us, that means building the prototype using Ruby on Rails, iterating on the user interface, and then eventually building the ‘plumbing’ beneath it after we have come to a 1.0 state of the interaction. That way, we are lean all the way up the fidelity curve, and our ‘spec’ actually gets baked into the final product.