Something that has bothered me for a long time is the idea of prototyping software. I think the problem resides in how other engineering disciplines view prototyping. For instance, in my days of designing circuit boards, we’d very often prototype a design to make sure it was going to fit our design constraints. There were several stages to prototyping: wire-wrapping or use an LPKF (a rapid PCB prototyping system) to create a very rudimentary board design, followed by several iterations of small PCB runs. Then you’d make a final production run.
Here’s the catch: prototyping was a step directly on the path to production. Before I made that final run, I had a prototype that I had used to prove out the entire product. It conformed to every signal specification, used complete and well tested components, and the only solid difference between the prototype and final product was that the final product would not have as many easy to access tap points for debugging. Here’s a diagram depicting that flow:
Writing software is nothing like that. A software prototype is inherently broken. Why? Simple. You generally forego all the things that make software production-ready: error handling, logging, input validation, unit testing, solid API design, and documentation. Additionally, the components are either partially implemented or completely mocked. If you try to take prototype software to production, you end up with a flow that looks more like:
So why do you do it? The same reason you start prototyping a PCB: to mitigate risk. However, you don’t need to use prototype code as the starting point. Andrew Hunt and Dave Thomas said it best in the The Pragmatic Programmer: “prototype to learn.” Prototyping is a learning experience. The goal of prototyping is to mitigate risk by ensuring that you can accomplish your design goals. Nothing more. Instead of trying to convert your prototype code into production level code, throw the prototype code away!
It’s counter-intuitive at first glance, but my experience has been that prototype code is so poorly designed it really does require major rework before it fits well into your product. But that’s not the bad part. The bad part is that you will have spent more time trying to make the prototype code work than if you had thrown it away. If you have the courage to scrap the code, the path to production looks like this:
Moreover, having the prototype there in front of you limits your view of the problem. I’ve often found that a much more elegant answer is developed when the code is out of sight.
Oh, and for those of you who think that the “prototype” code your inheriting from someone else is going to reduce your timeline, think again. When the only transfer of knowledge that happens between the prototyper and the developer is through code: you’re doomed. With a sizable code base, it’ll take years to make it to production–and that’s if you have a Free Electron helping you.