In my career as a programmer, I have done a lot of maintenance development. Some of that maintenance was on what are referred to as “legacy systems”. For those who don’t know, a legacy system is an application that is fragile enough that no developer wants to touch it.
According to Wikipedia, one of the characteristics of a legacy system (i.e. legacy application) is:
These systems can be hard to maintain, improve, and expand because there is a general lack of understanding of the system; the staff who were experts on it have retired or forgotten what they knew about it, and staff who entered the field after it became “legacy” never learned about it in the first place. This can be worsened by lack or loss of documentation.
I would add that a big problem besides lack or loss of documentation is incorrect documentation.
From a blog on Forrester.com:
- The app was written some time ago, its original authors moved on taking knowledge with them (lost knowledge).
- Subsequent authors changed the application based on insufficient / lost knowledge, introducing bugs and de-stabilizing it.
- The app is now brittle, and people are reluctant to change it for fear of breaking it.
The thing I remember most about working on these systems is that making changes was scary; you never knew what your change might break. That made me hesitant to make even the simplest of changes. It also forced me to overestimate the amount of time the change would take; I simply had to account for the amount of time I was going to spend testing the application after making my change.
The problem could be made worse by how critical these legacy systems were. Imagine making a mistake that causes peoples paychecks to be wrong (this didn’t happen to me but it happened to a co-worker). Imagine trying to explain how you let that bug through your testing to the executives. If your lucky, your management understands what maintaining these systems means. But, more often than not, management will think you were lazy or careless.
How Did We Get Here
How did we let things get so bad that we can’t maintain an application?
At the time many of these legacy systems were created, many of the practices and toolsets we take for granted today didn’t exist. There was no such thing as automated unit testing. Refactoring was avoided unless absolutely necessary because it was expensive. This applied regardless of how bad a piece of code was. Instead, comments were added to describe the functionality. Over time, this made the problem worse because the comments weren’t maintained and got out of sync with the code.
So, How Do We Stop This?
We avoid creating legacy systems by actively and aggressively maintaining the code base. We do this by refactoring constantly.
When code has good, thorough unit tests, refactoring is straightforward. You know that if the code passes the unit tests, it works. This also means that stinky code can be fixed immediately; it doesn’t have to age and get stinkier. This, is how we avoid creating a legacy system.
What Are the Benefits of Refactoring?
Here are the direct benefits of refactoring that I see:
- Code doesn’t get harder to maintain as it gets older.
- Code is cleaner, making it more likely we can add new features.
- Because of the above points, changes occur at a constant pace instead of slowing as the code base ages.
- It is easier to add functionality allowing the application to remain in use longer.
All of these add up to a lower cost of ownership for an application.
Why Dont’ All Programmers Embrace Refactoring?
Refactoring isn’t a panacea, it does have costs.
Refactoring Makes Changes Takes Longer
A change that includes refactoring will take longer, period. But it shouldn’t take much longer unless the code has gotten stinky because refactoring isn’t getting done.
However, without refactoring, an application can quickly turn into a legacy application where any change is ridiculously expensive. So while refactoring does incur a cost in the short-term, it incurs significant savings in the long term.
Refactoring Can Introduce Bugs
Any change we make to code can introduce bugs. That means refactoring can too. The one thing that helps refactoring though is quality unit tests. If the tests are thorough, you can be confident that the refactored code is functionally equivalent to the code being replaced. This seems to me to be a small price so that I can have an application I don’t mind maintaining.
Refactoring Doesn’t Add Value
It is true that refactoring doesn’t add new functionality. Some programmers equate this with refactoring adding no value. That is a short-term, if not immediate-term view. If you look at the long term, refactoring makes an application easier to maintain which means future changes will cost less. This can also lead to an extended life for an application which can result in significant cost savings.
So, embrace refactoring. Used properly it is a tool that will benefit you, your project team, the applications you write, and the customers your applications support.