Software development influencer Joel Spolsky specifically forbade rebuilding software from scratch. He called doing so, “the single worst strategic mistake that any software company can make.” That blunder’s disastrousness is evidenced by several historical examples. Those cases are reinforced by an assortment of impressions. These perceptions lead a developer to conclude that he must reconstruct a program from scratch. Yet, an engineer should rarely bulldoze an application and replace it with newly forged software. A programmer should only consider rebuilding a product entirely if he is able to check off the boxes described below.
A requirement for recreating an application from the ground up is a deep, detailed knowledge of the software. A program acquires hairs (some of them ugly and nasty) in the form of various bug fixes. Those unshaven corrections represent accumulated knowledge. That expertise is tossed out when a codebase is rewritten from scratch. Bulldozing a product to build a shiny new one is akin to tearing down Chesterton’s fence. That barrier represents a state of affairs about which a reformer (or developer) knows little. The revolutionary tears down the barricade, believing that it serves no purpose. Yet, the fence in Chesterton’s fable has a purpose, which the insurgent realizes only after tearing the wall down. The boundary of the poet’s tale is poorly understood software. The reformer is the programmer who wants to rebuild a program from the ground up, without understanding it deeply first. Both the reformer and the developer encounter troubles, without first acquiring knowledge of what they want to bulldoze.
A developer decides, upon working with a particularly unsightly legacy application, that he wants to remake it from scratch, yet he fails to produce a program better looking than the old one was. The newly built software makes progress. As it moves forward, it began to acquire various warts, ugly hairs, and wrinkles. The new codebase is at least as unattractive as the old one was. The hideous features in the previous version were bug fixes that the programmer thought were merely blemishes. The developer made a category error. He did not bother to understand the application he was rebuilding. His reconstructed program is, at best, no better looking than its deformed predecessor was.
A pleasantly rebuilt codebase requires not only deeply understanding the existing application but also learning lessons from that product. Insights lead to increased knowledge. An expansion of wisdom is a prerequisite to a better result. That extra expertise is required to avoid the mistakes that precipitated the flaws in the existing codebase. Those defects, or different ones, will be built into the reconstructed commodity. The program is built by developers whose knowledge is, at best, equal to the engineers who built the original codebase. The new programmers will make the same missteps, or different ones, in the rebuilt application as old developers did in the existing program. The rebuilt product will be just as ugly old one as if the developers do not learn any lessons from the existing commodity.
A team of engineers reconstructs that application, but it fails to create a commodity less unsightly than its predecessor was, leaving the group perplexed. The developers had knowledge of the product, so they wondered, “How did their unit flounder in its efforts to produce a more attractive successor?” One might respond, “Did the programmers learn any lessons from that expertise and could they articulate them?” The team could answer. “Yes.” Its interlocutor would reply with the question, “What insights did the engineers gain?” The unit is likely to stare blankly, revealing that its developers had not thought deeply about the matter. The group had acquired wisdom, but it could not articulate it. Any lesson learned is likely to go unapplied since the programmers are not aware of it enough to act it. With many advances unutilized, the rebuilt application ends up as unsightly as previous one was.
To reconstruct an application from scratch and to make the rebuilt version less unappealing than its predecessor was, a team of engineers must identify applications of lessons learned, not just spot those insights. Lessons do not inevitably lead to improvements. Advances must be consciously spotted by developers to build a more appealing codebase. Improved programs stem from the utilization of insights, not the lessons themselves. Wisdom is merely the prerequisite to the improvements, which lead to a less unsightly product.
The current product can have breakthroughs culled from insights applied to it by a team of developers, just as a reconstructed codebase can. Programmers are not inherently barred from leveraging its acquired knowledge to apply advances to an existing application. A unit can clean up a commodity’s existing architecture or refactor its code just as easily as the group can build a clean architecture and write clean code, in theory. An existing design can be scrubbed clean through the consolidation of class hierarchies and the cleanup of component interfaces. A new blueprint can be disinfected through neat groupings or loosely coupled components. Improvements pulled from lessons learned can be applied to an application built from scratch or the current application, if one ignores the context in which developers apply for those advances.
A team of programmers can only apply certain insights, in certain situations, to an existing product or reconstructed software, while other experiences can be applied, in other contexts, to both. For example, an application’s architecture might be so tightly coupled that it cannot possibly be cleaned up, without demolishing the codebase. That program’s design can only be cleansed in a complete rebuild. Another commodity’s blueprint might be messy and wasteful but not tightly coupled in an egregious way. Such a layout can typically be consolidated and scrubbed clean, with an effort commensurate to the application’s size, making totally rebuilding the application inadvisable. Other programs exist between the two extremes, requiring that a unit weigh the costs and benefits of fixing the current application or reconstructing it from scratch. The context for improving a specific product is unique. Not every insight can be applied, in every situation, to an existing commodity and to one constructed from scratch, requiring that a team evaluate each circumstance independently.
A unit of programmers frequently desires to demolish and rebuild a program, an instinct that is typically mistaken. Such a hunch should only be followed, if the group actually understands the codebase it wants to rebuild. Moreover, any developer, let alone the collective unit, must be able to articulate at least one insight gleaned from his experience, prior to moving forward with the demolition. That wisdom should lead to at least one application. The costs and benefits of each approach for the current product and the rebuilt one should be weighed against one another. If the gains and outlays point towards the demolition and reconstruction of a product, then a team should proceed, otherwise another path towards improvement is wiser. Typically, an approach other than total demolition and reconstruction is the more prudent one, as Joel Spolsky stated more than a decade ago.