Prototyping, a forgotten Design Practice
Amongst the gazillion myths about Agile, one of them is “Agile means no design, its a cowboy coders’ feast”. Give me a break, you think its cool to pretend that code just flows out of your fingers without any design/thinking? Why is thinking about design before coding production code looked down upon? I completely understand the pitfalls of big upfront design and I’m not proposing that. Whether you use CRC cards, white board, acceptance tests, mental models or whatever have you, you are designing. You might not think about it as traditional design. But think about it, you are actually designing. And there is nothing wrong with it. You are not a poor developer if you do that. In fact as I know, some of the most respected programmers in the industry do some form of design before they code production code.
In fact I claim that when you are breaking down your user stories you are designing your software. I actually have an example of how breaking down your stories differently can lead to a very different design. In this blog post, I explain why.
One of the things that I have found very useful when building software is to just prototype 2 or 3 different approaches, to explore the problem domain, before actually TDDing the whole solution. Recently I added version control support to FitNesse. The approach I used was I tried first logical solution that came to my mind. It worked, but as I started using it, I need more stuff and the design I had would not really fit well the new requirement I had. I could have incrementally refactored the design to suite the new requirements, but since I treated the code as prototype, I threw it away and started from scratch. It seemed a lot less effort to throw it away and rebuild it from ground zero. Again this time, I just treated the code as prototype. I was really exploring a new idea and I wanted to test the design by writing some quick and dirty code. Usually these sessions might last a couple of days. These are clearly not months worth of effort.
It turned out that my second design worked for single user, but would not work for multiple users. It had a fundamental design problem that I could not have thought before hand. (May be some other smart people could have found it before we started, but I could not. May be having a pair would have helped, but this was open source and I did not have a pair). Again this was a quick and dirty way to get a high level design feedback.
This style really complements the whole TDD philosophy. Its not that you do a quick and dirty prototype and you don’t need to do TDD any more. Prototypes really help you explore a broader aspect of your system design than TDD can do. TDD helps get feedback about your design and also helps build a safety net, but there are multiple design options and TDD helps you achieve one of those designs. How do you know if there is some other class or library that can actually work, sometimes TDD can help you with that. But if you are completely unaware of its existence, you would need an exploratory session to figure out your options. Once you know what options you have, TDD can really help you solidify it. Hope you get my point.
Sometimes, I write a high-level automated test and build various prototype. The automated test really cuts the manual check at the end.
Prototype is similar to the spiking practice that XP suggests. Somehow spiking has really fallen of the face of the earth. But XP really recommends you spike out various approaches to solve a problem, pick the best and then TDD the solution.
Prototyping is not a new practice its been around for ages. In fact its been around not just in software but also in other disciplines (craft related) like painting. A lot of times, painters create clay models of their subject to understand the depth or other dimensions about the subject. This really helps them give the real feel to their painting.
Now that your are convinced about the importance of prototyping, the next question is should you always prototype? Of course not. If you are not sure about the design, if you want to explore the problem domain, or if you think there is high technical risk with what you are building, sure. Else its just ritual (waste of time).
So when does prototyping stop? At some point you might feel confident enough that you understand the problem domain enough and you can switch to TDDing your production code. But if the requirements changes and something fundamental on which your design decision was based changes, you might be able to just incrementally refactor your design to suit the new requirement. Sometimes, you hit the point where trying a prototype and throwing away your existing design might be the best option. You are the best judge.