|For novel ideas about building embedded systems (both hardware and firmware), join the 27,000+ engineers who subscribe to The Embedded Muse, a free biweekly newsletter. The Muse has no hype, no vendor PR. It takes just a few seconds (just enter your email, which is shared with absolutely no one) to subscribe.|
By Jack Ganssle
Software rots. Age is unkind to it. Just as people acquire aches and pains as the years progress, code tends to run down.
Young programs are slight, sprightly things that respond like gazelles and eat little disk space or flash. Bugs and misunderstood requirements frustrate users, but few expect much maturity from adolescence. With time and tuning the code seasons and becomes a fully productive part of a business process or product.
By middle-age patches, improvements and creeping featuritus bloat the girth and hobble performance. The graying code slows and swells, though still satisfies users.
Continuing bug fixes and ever more features drive the software into old age. Now annoying glitches and oddly interacting components deliver at best arthritic capabilities. Only heroic intervention at great expense staves off the inevitable. Cancerous growths - forks controlled by hundreds of poorly understood #ifdefs - metastasize recklessly. Comment drift renders all documentation gangrenous. Deft surgeons remove chunks so infected they're useless and graft repairs onto essential organs.
The code acquires the moniker "legacy application," that label reserved for a program that's still needed but is so old and decrepit that maintenance costs soar. Some companies have a culture that respects legacy apps. In most they're considered a burden supported by the lowest paid developers, who resent the impact on their lives and careers.
When the cost to modify the code exceeds the value to the customer the program is either pensioned off to unsupported status or is euthanized, eliminated from the company's product portfolio. Sometimes it's replaced by a direct genetic descendant, a completely new, rewritten package whose design is drawn from the ancestor's structure but which exhibits all of the desirable attributes of youth.
And then the process repeats, with each generation evolving towards a higher level of complexity, better suited to fit the new, changed nature of the computing environment, then aging, eventually being buried 6 bits deep.
What a terrific waste of resources.
Death is an inevitable part of all life cycles. At some point a program simply meets no need. The world changes and requirements disappear. But all too often we kill off the software because of the creaky joints; it's simply too difficult to maintain.
And that's an even more terrific waste.
Wise developers build the code from the ground up with robust DNA that's impervious to the damage caused by cosmic rays of real-world change. They create an immune system (documentation, structured code, extensible design) that bends to the inevitable assaults rather than brittlely collapsing.
But once launched the program is under the care of maintenance custodians, who might wreak havoc faster than the Ebola virus. Maintenance can be a careful process that applies wrinkle cream to defer the inevitable fate of the aged, or a process of rubbing soil into an already infected wound.
Legacy apps are often the core software that creates the bulk of the company's profits. Yet we dump support on the newbies who hack quick fixes, invariably breaking other features. They're untrained and inexperienced. Patches accumulate, each a little bit of ugliness layered on top of earlier mistakes.
Great maintenance people don't slap a poultice on the exposed wound. They grow a culture, determine the illness's root cause, and then inject exactly the right antibiotic. The patient recovers, healed, with neither scars nor lingering infections.
The cost of great maintenance is high; but that of poor support is ultimately even higher.
How do you prolong your product's life?