The Danger Of Software Prototypes
CTO and a co-founder of VyOS.
getty
It’s no secret that software design is difficult to get right from the first try, which is why software development often starts with a prototype. Unfortunately, prototypes don’t always serve their purpose well—they are supposed to be discarded if the solution concept turns out wrong, but instead, they are often deployed in production before they are fully validated. That leads to expensive rewrites and migrations—precisely the problems prototypes are supposed to prevent.
Many books and articles emphasize the importance of throwing nonworking solutions away. A quote from Fred Brooks’ The Mythical Man-Month even became a programmer’s adage: “Plan to throw one away; you will, anyhow.”
That wisdom seems almost trivial and redundant. When people work on completely unsolved problems, they make prototypes and naturally throw them away. No one gets attached to code that obviously isn’t working and can’t be made to work.
Bad prototypes often live much longer than they should because there are other factors at play, such as sunk cost fallacies, insufficiently analyzed requirements and overzealous belief in iterative software development. Problems often look simpler than they really are, and the pressure to ship combined with the belief that anything can be fixed later leads to expensive mistakes. That is why it’s so important to recognize those fallacies and know when to throw a prototype away.
Sunk-Cost Fallacy
In software projects, there’s always pressure to ship. Continuous integration and delivery are good trends, and shorter development cycles allow developers to get feedback from users early. However, it works best for established projects where the fundamental problems are already solved.
When a team working on completely new software is pressured into shipping it as soon as possible, they may have to choose between shipping code with known fundamental issues or being reprimanded for not shipping anything for too long.
Most managers know that “we spent a lot of time on this already” is never a good justification for shipping anything. Of course, no competent manager will force engineers to ship code that cannot work, no matter how much time it took to write.
But for nontechnical managers, it’s easy to underestimate how serious the problems are, and engineers themselves may not be given enough tools to either validate the solution or convince the managers that the prototype is fundamentally flawed—they need precise requirements to do that.
Insufficiently Precise Requirements
One reason why “plausible but wrong” prototypes are common is that many problems in software development aren’t completely unsolved, and it’s easy to come up with a superficially plausible solution quickly. A lot of business software is really CRUD (Create-Read-Update-Delete) applications—the algorithms involved aren’t complex. If they don’t serve their purpose well, a lot of the time, it’s not because the programming problem on hand is hard; it’s that the developers either didn’t implement the real end users’ requirements correctly or didn’t even have complete requirements in the beginning.
For example, any qualified full-stack web developer can throw together a plausible prototype of a helpdesk system in a week. It will even suit the needs of at least some users in that rudimentary shape. What many helpdesk systems on the market lack isn’t basic ticket submission and tracking functionality; it’s much more subtle features, such as support for multiple products, SLA tracking, knowledge base and download portal integration and so on. If a prototype was designed without the possibility of different ticket handling rules for different products and SLAs, it might be very hard to add that functionality later.
Thus, requirements gathering is a crucial step, and it’s essential to make sure that they are precise. End users who aren’t programmers or professional analysts may also easily miss essential requirements.
It may be a good idea to observe their processes and ask about their future plans, rather than just ask what they want right now because some software architecture decisions are very hard to change later.
Overzealous Belief In Iterative Development
Certain development methodologies like “extreme programming” emphasize rapid iteration—in essence, they call for never throwing prototypes away but trying to evolve them instead. With my helpdesk system example, it may be plausible.
In other cases, it isn’t. For example, thread safety must be designed upfront and constantly maintained afterward. Efforts to convert formerly single-threaded codebases into multithreaded can easily take years to complete, and the program will not be multithreaded all that time because even one unsafe function can ruin it for the whole program.
Even when an evolutionary change is possible, when a prototype is already in production, it may require labor- or resource-intensive migration to correct the wrong assumptions in the already existing code and data.
So, maybe more useful advice would be “gather enough requirements to know when to throw your prototype away” rather than just “prepare to throw one away.” If you don’t know whether your software does what its end users expect it to do, you can easily spend more time working on a dead-end prototype than you would spend on planning and design. And if you write a prototype that has to be thrown away, you will know that the decision to throw it away is correct and can defend a decision to start from scratch.
Forbes Technology Council is an invitation-only community for world-class CIOs, CTOs and technology executives. Do I qualify?