Prototyping, tracers and the art of throwing things away

I’m a fan of prototyping. Not all the time but I strongly believe that it has a place within the toolkit.

If I am unsure of how something might be put together then I might put together a quick version to test out a current approach. If I am working with a team who know what the outcome needs to be but are unsure of the way it needs to be done, then writing something that echoes what has been discussed is often a great way of focusing meaning and decisions. Sometimes I find it useful to force decisions when there is endless procrastination or that I see ideas that are not fully formed.

So I find it useful for focus, getting decisions made or just helping to identify parts where a more refinement is required.

A prototype is to be thrown away though.

It demonstrates and cajoles but it should not last into the fully fledged version of the software. Jeff Atwood on Coding Horror calls it “The Prototype Pitfall” and lists Tim Weaver’s 5 laws of prototypes. Sadly, I know that number 4 is true: once a prototype is deployed, you will never get around to fixing or improving it unless a bug is filed. (Even then, it may not be fixed.) Prototyping standards are not production standards.

The purpose is to write a minimal version of what is being achieved to help everyone understand the complexity or the missing requirements. It aids the conversation and provides valuable learning points but is then thrown away.

From that code, the teams should understand the domain in deeper depth and learn from it, rather than repeating the same errors. I think that it can also support Domain Driven Design by forcing the points of non- or misunderstanding into the open.

Using the Pragmatic Programmers’ words, Atwood discusses the Tracer Bullet approach. Rather like a prototype, the basic system is mocked up. Instead of being something that is thrown away, the tracer provides a minimal implementation of the system that can be iterated over and developed into the fully fledged system. If an algorithm is required, put in the basic version: it can be optimised and improved later. If a remote call is required, provide a stub.

Towards the end of the article, a useful point is made about how to make the prototype more disposable whilst being useful:

I think it might help to develop prototypes in a totally different language or environment. That’d reduce the temptation to code around the prototype

For instance Python could be used where the final code would be C++. A simple UI could be put together using static HTML5 and some JavaScript though this might turn into a Tracer Bullet event (Dan North describes a colleague doing this in his “The Browser is Dead” talk at GoTo 2012). A choice needs to be made about intent and only the developer or development team can do that.

In a recent project, I used the Tracer Bullet approach to create a framework using Flask and relatively simple JavaScript with some mock interfaces behind it where required. Using this, I was able to have a meaningful conversation with the other team members leading to a better understanding of the deficiencies of the data, assumptions made in the specifications given, and defects in the specifications given, such as little real thought about how the user would interact with large amounts and varied types of data.

As part of the refactoring of the code, the underlying code is becoming aligned with the various project principles and architectures. The initial version of the code did not need this but the final versions will use them. Colleagues have already commented that they want to have places to extend the code base so it has been updated to reflect this and allow requirements without writing large amounts of code to support it. To some degree, this follows the open to extension, close to change principle.

So I still love prototyping as a tool but it will only be useful if the caveats and restrictions are applied to it: throw it away. If it is going to be used, then use Tracer Bullets.