A boss of mine once told me, “Sometimes getting something done quickly takes precedence over doing it right”. I’d argue that “quick” and “right” are the same thing in this context; it’s simply a pitting of the long-term against the short-term. Consider the time it actually takes to get things truly done. Well, yeah, I could push out a quick and dirty solution in a few minutes, but I can almost guarantee that it will bite me back when I least suspect it. And I’ll stand up dazed and confused, not knowing where the problems came from. What I will finally come to realize is that the project wasn’t actually finished; it was merely in an unstructured beta test.
Over our careers, we’ll churn out a lot of short-term projects that end up getting scrapped as fast as they started. It’s inevitable. There is little incentive to spending time improving maintainability for something that will not likely be maintained. But how do we handle that rarer project that does end up with a long and bountiful life? The way it stands, we’ll just wait until it gets sick and let it subsist on some expensive life support machine. But if you intend to live a long life, as countless health and financial experts have shown, you better start planning early.
For this reason, “prototypes” should be identified as such, so that they can be treated appropriately. One of the reasons that prototyping is a favoured method of production is that it allows for a quick implementation, for the purpose of gauging the product’s value. Still, the method gets a lot of flak due to the more common use of the prototype: as a full-fledged product. The result is that many prototypes end up on the market claiming to be the brainchild of a solid process, when it is no more than the bastard son of a cheap and dirty production line.
One of the reasons that many developers prefer to code with no design is that it really helps to get the code on the page and understand how the concept might work. Essentially, code devoid of design is just a prototype. And that prototype can be used to form a good design. The design really is in the details.
Given the unfortunate – but realistic – assumption that most code is poorly documented, we can hypothesize that the developer mentality is prototype-oriented. Whether this is an inherent trait or inherited from management is a moot point, and ultimately a job for the social psychologists. What matters is how this affects our ability to enforce standards and good documentation. It all comes down to making a distinction between prototype and product.
For those prototypes that inevitably become products, there must be an identifiable point in its life where this classification changes. How can you identify it? Picture yourself with the satisfying job of rejecting prototypes all day long. You’re a “no” man. All you do is scrap prototypes. But the exact moment you’re forced to say “yes” to a prototype is the moment it becomes a product.
Most of us are geared to continually say “yes” to a prototype, and then say “no” when we finally receive some metric that conclusively proves its poor performance. But the point where you would scrap the prototype can be the same point where it becomes a product. And if you’re really good – if you’re really a visionary – you can spot these tendencies even before the results come in.
In any case, the exact moment where you choose acceptance over rejection is where you must focus on maintainability. If you don’t plan on building a design from what you know and then starting from scratch, then you absolutely must make an active shift from the prototype mentality, where documentation, conventions, and standards don’t matter, to the product mentality, where these things lead to a maintainable and manageable software solution.