Prototypes and the myth of disposable code

A lean and experimental approach to development suggests that features can be proven in quick prototypes before being implemented "properly" in a production context. Alas, things never quite work out that way.

This is a familiar story. A team build out a proof of concept to demonstrate a new idea. The resulting prototype cuts a lot of corners, but this does not matter because they are only trying to explore an idea. The prototype is a success. Customers take an interest. The business gets excited.

The prototype gets sold. The team come under pressure to put it into production. Nobody can quite understand why there is so much reluctance among the engineers. After all, it works, right? Why should we invest in building it again? What do you mean by "doing it properly"? Couldn't you do that the first time around?

There's no such thing as disposable code. Anything that an engineering team writes can get press-ganged into production as commercial imperatives steamroller any concerns around scalability and resilience.

You can present something as "beta", "trial", "tactical", or "experimental", but to non-technical stakeholders it's all working software. It's difficult to explain just why the quick prototype that you have knocked out will never be ready for primetime.

Prototype or proof of concept?

The terms "proof of concept" and "prototype" are often used interchangeably, though there is a difference between the two. A proof of concept shows whether something can be built, while a prototype attempts to bring the concept to life by building a working, interactive model. A proof of concept is a test of whether something is achievable, while a prototype addresses the question of how to build it.

In engineering terms, there is little practical difference between them. They both describe an approach to solution development based on exploration and experimentation. They are both used to test the feasibility of a solution. They can both be misinterpreted in precisely the same way.

The problem here is the assumption that you can throw away anything that is created as part of the experiment. This can open the door to all manner of corner cutting. Lightweight tools are used to create faster visualisations that won't cut it in a production context. Engineering concerns are put to one side in favour of generating ideas and mocking up features.

Any finished prototype or proof of concept will demonstrate features that will have perceived value. They are unlikely to surface the compromises that have made along the way. This is something that needs careful explanation to stakeholders, and it's rarely engineering teams who end up doing the explaining. Nuance gets lost in the excitement and desire to win support for a product.

All stakeholders see is something that works. They won't think about the duct tape and chicken wire that lives underneath. And why should they?

Demonstrating value and viability

If you are trying to demonstrate the value of an idea then you should also be demonstrating its viability, i.e. that it can be developed as a production-ready application. If you cut corners to get something out quickly then you are not really demonstrating that it can work in a commercial context.

This isn't an invitation to gold plate everything. You can still iterate, experiment, and build quickly, especially with modern development tools. However, you should always build with a clear view route to production for the application.

This means adopting an evolutionary approach to architecture that builds the capacity for change into your application. You should be able to establish a basic, skeletal architecture that can prove out the functionality while leaving placeholders for production concerns that can be added later on. This basic architecture will make it easier to envisage the effort and complications that might be involved in building a production system.

You should also bake in some level of test and deployment automation from the start. Other supporting infrastructure can wait, though you will at the very least need a strategy for ensuring scalability, enabling resilience, and providing the means to support the application in production.

This can still be an experimental application, but one that recognises the reality that the code is being used to demonstrate commercial viability. It won't be thrown away once a point is proven and is likely to be used as a foundation for a larger system.

Proving functionality alone is not enough. Almost anything can be made to "work" by hacking together a bunch of scripts or "low code" tools. You need to prove that it will work as a commercially developed application. That means striking the right balance between lean agility, engineering practices, and architectural rigour to allow new ideas to take shape in a commercially viable context.