Friday, June 29, 2012

Why prototyping is your best friend

There is no doubt that the single most challenging problem in software engineering is getting the right requirements in order to build the right product.

The problem of requirements occurs for a number of reasons. Very often, the customer does not know what they want exactly. "I want a system that will make our collaboration better," they might say. For any software engineer, this can mean a hundred different things. And even when the customer has a reasonably clear idea as to what they want, the thinking process generally happens in such an abstract way that makes communicating the idea rather difficult. You see the customer talking and using their hands and drawing circles in the air to explain to you how they imagine things, and you know that they have something specific in mind, but they're having a hard time explaining it. And even in rare cases, when the customer can explain what they want really well, the problem of terminology comes to the picture immediately. For one, customers usually (and rightfully) use their own domain language to explain things: "This feature should allow the user to inject the data and put it in clusters." And second, the communication between developers and customers regarding design and implementation has no common ground. You listen to developers talking about a control panel, and a navigation window, and a workspace.. The customer would be nodding their head in agreement. But experience taught us that this nodding usually means one thing: "I get what you are trying to say in principle but I'm not sure if we're talking about the same thing."

Luckily enough, prototyping can conquer all of these problems in a very elegant and smooth way.

Prototyping involves building a quick-and-dirty mock up of how we envision the system to be or look like in the near future (months in the agile world). Especially nowadays, as the focus is moving more and more into building GUI-intensive systems, you might want to consider prototyping the UI without worrying much about the underlying functionality.

How do you start?
  1. Sit down with the customer and the key developers involved, and try to come up with a few use cases (scenarios) of the system under development. Make sure this happens strictly in the language of the end user not the language of software developers. You don't need to exhaust all possible scenarios - just the main ones for now.
  2. Give your team the chance to think about it and ask questions. Then, in the same meeting, assign the task of coming up with the first UI prototype to someone (or a pair). This is an essential step, because you need a starting point before you convene again. Otherwise, you will drown in an endless discussion before you could even draw anything on the board.

    Also, set a firm and short deadline for this to happen. For example, I prefer the next day as a deadline. This has many advantages. First, prototyping is best when the discussion about the use cases are still fresh in your mind. More importantly, you don't want the person with this task to spend a lot of time trying to perfect the prototype or make it look beautiful because that would be counter-productive in this phase. Also, the product of one-day worth of work is going to look dirty, and this helps in focusing the attention of everyone on scrutinizing the content rather than the look (in this phase), and it helps convey the message that this is a very rough prototype that is in severe need for everybody's input. Finally, we have learnt from our dark history with requirement documentation that the more time and effort we spend on an artifact, the more we will resist changing it later on. Therefore, you don't want the prototypers to get emotionally attached to their initial design.
  3. Convene again and ask the person tasked with prototyping to draw their initial design on a whiteboard, and explain it. A whiteboard is all you need. No computer designs should be involved - again because psychologically we are inclined to resist changing a computer-produced design as opposed to a hand-drawn sketch on the board (aka. low-fidelity prototype). Look at these two prototypes for example:


  4. Have a few rounds of discussions on the presented prototype, and change it as needed. Depending on how this goes, you may need to spend two to three days on this activity. It is a good idea to break the meeting when you reach a dead end in your discussion or when people are too exhausted. Come the next day with fresh ideas and open the discussions again. Once your prototype starts to change only in the fine details, stop the discussions and move on to the next step.
  5. The team should spend the next few days on a quick spike to transfer this prototype from the whiteboard to an actual UI everybody can see on a computer screen (i.e. high-fidelity prototype). Use the intended language/platform to prepare this prototype. For example, if this is a web-based application, you might want to use HTML, CSS and Javascript. If it is a WPF application, use C# and so on.
  6. Only UI elements and the main interactions should be included in the prototype. The underlying functionality (communication with the server, DB connections ... etc) should be ignored for now. To replace the missing functionality, use mock-up objects and files to fill the UI with close-to-real content. Also, the aesthetic details should not be a concern at this point. Remember that this is still a prototype and should stay as such until you decide otherwise. 
The whole process above should not take more than a couple of weeks, during which you can iterate as needed to come up with a reasonable approximation as to what you envision your system to be. Setting a deadline for the prototyping stage might be important depending on the culture of your team.

Did you get your prototype ready? Let me tell you what you have just achieved.

First of all, you created a common vision for the whole team - something that you would otherwise struggle to do. The prototype you created will serve as a point of reference to remind everyone on the team of what it is we want to accomplish. And best of all, this reference prototype will facilitate future meetings and discussions. You will always have it handy wherever you go. Your customer will come to you and talk about this specific window and that specific button. What you did there is share your technical terminology with your customer, and at the same time, you will find yourself starting to talk your customer's language because he/she was involved in making this prototype in the first place. (Read Eric Evans' book on Domain-Driven Design for more on the importance of nomenclature in software development).

From a project management perspective, planning and estimation becomes a much easier job. Given a prototype that - to a reasonable degree - reflects what we aim to achieve, we can now breakdown the work into deliverables, plan releases and iterations, assign resources, assess risk, and set expectations.

Finally, your prototype should always, in my opinion, lend itself as a prototype and nothing more than a prototype. The aesthetics of it, the color schemes, the layout of UI components should not give the impression that it is a final product. Otherwise, you will lose some of the key advantages of building a prototype such as gaining focus. Later on, as your customer becomes less concerned with the general vision, you can always fine tune things to start discussing the design itself.

Your prototype is indeed your best friend, but no matter where you guys hang out, never lose your friend at a beer garden!