I’ve become morbidly obsessed with decay these days. My dentist doesn’t help but she’s nice about my receding gums and minor cavities so I let her off. But the more I look the more I see the decay, all around me.
I recently took this photograph on the back streets of my town. The “Bamboo Bar” is long since abandoned but the newish bicycle suggests that perhaps there’s life inside. This abandonment theme is so common in Cyprus that it’s almost invisible. In some places the contrasts are stark, the new and glitzy sits yards from the old and beaten. Large stretches of land are waste ground not because it’s a waste-land but because the owners bought the plot a long time ago and will build a house. One day. Until that day the weeds grow tall and the tumble-rubbish piles high. Things in Cyprus take time, I have to remind myself to never forget that.
This theme pervades through all areas of life and I guess it happens everywhere it’s just the contrast here seems stark.
But what of software? It seems ludicrous to claim that software can decay because: it is abstract, has no moving parts and isn’t exposed to the environment. This seems true enough. But suppose such a notion of decay could be applied to software. If there’s no physical environment to aid decay then what environmental factors could there be?
Changing Requirements = Shifting Sands
For me this is the biggest challenge that faces us as software engineers. The shifting sands of requirements are real. Pinning them down for the delivery of the initial project is probably vital but once you have released the software the requirements can and will run free. Mentioning to your boss that ‘we didn’t factor that in to the original design’ sounds like an excuse and could seriously damage your bonus.
But what if new features are successfully added? New features can be added that upset whatever balance the application may of had. Over-time those new features could become poorly understood code dead-ends that end up polluting the source pool forever or even central aspects of the system (possibly eclipsing the original intended purpose of the software).
This consuming phenomenon can be seen in the physical world too. I used to own a series of bangers each car worse than the first. The worst purchase drove for about 100 miles and then needed a new engine. Others became accidental projects for an impatient and inept mechanic. Me. I remember the dawning horror when I realised that part of the problem with my Mini 1000
was that I was putting new parts into it. The new parts would operate at peak efficiency in amongst a rotting husk of older parts. Those old parts surrounding the new parts understandably promptly failed under the new load. I did a lot of walking in those days.
Analogies are often imperfect and comparing cars to software is no different because software components don’t wear out! However, when the the requirements change you might replace one component with one that serves a slightly different purpose. Our replacement component might compromise the original design assumptions. We can do this successfully for some time, but we will eventually end up with a loss of direction. If things are going really bad you might even have a loss of vision.
Loss Of Vision & Bad Maintenance = Death by a thousand cuts
Every large project will have at least one or two architects. Those people are the knowledge-holders of why the system was built and what trade-offs were made and why. Over-time you will lose these people and when they’re gone you’ve got a problem. If the system is sufficiently large you will probably find that no one person has that original knowledge and when changing requirements happen the people you still have end up misunderstanding the code or taking shortcuts rather than refactoring. And this is undoubtedly because of Joel:
It’s harder to read code than to write it.
So, in my opinion any medium-to-large in-house software project decays. There’s no physical decay but any useful be-spoke software project will probably change as the business changes. The more time passes the further the source pool migrates from order to entropy and the harder to maintain and less efficient it becomes.
Running to stand still
The inevitability of this decay means you’ve got to do some things up-front in a new project to try and prevent your software being like my beloved Mini 1000
- An identifiable design. This is largely impalpable but if a single person designed the original system and the coding standards were reasonably tight you might produce an identifiable design which others can follow. Of course design operates on many levels in software and when it comes to maintenance the chances are only the low-level design will be seen, the high-level design will probably be invisible to most.
- When the knowledge-holders leave there is sufficient transference of understanding at all levels of the code. This probably also broaches the tricky topic of documentation
- Finally, some of that knowledge can be encapsulated in tests (unit and integration). So that when we do end up on shifted sand we can at least assert that what we have now is of comparable quality to what we had then.
As for the “Bamboo Bar” I think its ship has sailed. My Mini 1000 is probably starring in a Scrapheap Challenge now. But I’m not sad, decay in some things can be beautiful. Sadly, my software is like my teeth. Decay doesn’t become them.