I’ve been concerned a lot recently with so-called legacy systems: what they are, how to work with them, and so on. I think they get a bad rap, and one of the major reasons is because the concept of a legacy system is so badly defined. I find a lot of people and organistions are working perfectly effectively with what outsiders call legacy systems. If the organisations are working so effectively with them, what makes them legacy?
Setting out the definition
Here’s my definition of a legacy system, and I’ll go on to justify why I think it’s important to get it right:
A legacy system is one which resists change
Similarly “legacy code” is any code which resists change. To be honest I keep tweaking this definition, but generally I keep returning to that form. Other ideas are welcome.
Getting the definition right is really important, because when we apply the right label to something it gives us quick routes to practical conclusions. Conversely, misapplying a label results in misunderstanding and the inability to do anything useful with what the label implies.
Getting the definition right for legacy systems is important, because “legacy system” implies a particular set of problems, and if we recognise common problems then we can more easily identify and share solutions.
Characteristics of legacy systems
Here are some problems typically associated with legacy systems:
- It is time-consuming, risky and/or unreasonably expensive to introduce new features
- Limited knowledge within the organisation as to how it works
- Lack of vendor support
- Skills shortage in the marketplace
- Integration with other systems is cumbersome or complex
- Business processes typically work round it, rather than vice versa
It’s valuable to capture these and similar characteristics in a neat phrase and label it “legacy system”. If you and I have these problems, and you have experience solving some them, then perhaps you can help me out. And it’s a lot easier for us to identify each other and the help on offer if we can communicate through a common language. The definition of “legacy system” has practical value.
Now here are three definitions of “legacy system” or “legacy code” which I find lacking:
- “Legacy code is code without tests”. That’s Michael Feathers’ definition in his book “Working effectively with legacy code”.
- “Systems and applications that have been operationally embedded within a business function but superseded by newer and often more effective technologies or changed business needs”. That’s from the NAO’s September 2013 report on “Managing the risks of legacy ICT to public service delivery”.
- “An old method, technology, computer system, or application program” according to Wikipedia. (Although it confusingly goes on to say “The term “legacy” may have little to do with the size or age of the system…”.)
The most telling story for me about defining a legacy system was related to me by an IT director: She had a new project which involved some deeper-than-usual changes to a particular system. One of her developers had told her that he was particularly unhappy about being selected for this project because he expected to be working on the newer technologies in the company. Some of his colleagues felt similarly. Yet the project’s technology was robust and modern by most external standards. It was no older than five years (and it was considered modern then), well-written, had comprehensive and reliable tests, was continually evolving (at least in the outer layers), regarded as high quality, and gave the organisation an acknowledged competitive advantage.
It was clear to me then that “legacy” is a relative term. That code was legacy in the mind of the developer and some of his colleagues. If the director had wider problems evolving the system, perhaps because of wider resistance in the development team, then it would have been considered more widely as a legacy system.
That’s partly why “code without tests” doesn’t cut it for me as a definition. Also, consider an older system without automated tests. Before automated tests were the standard, that same code would not have been considered legacy in any practical sense. And if the same developers are able to continually evolve it just as they did all those years ago (still without tests), and it’s still meeting stateholders’ expectations, then it displays none of the characteristics of legacy code that I listed above. (As an aside, I should add that I think writing code without tests is crazy, but I do acknowledge that if a company regards that kind of practice as acceptable then they don’t have what they regard as a legacy system.)
The NAO’s definition is pretty good, but it still lacks something. The key phrase is “superseded by newer and often more effective technologies or changed business needs” and there are two parts to this. First, just because something is superseded by newer technologies it doesn’t follow that it has the characteristics above of a legacy system. It may be superseded, but if there’s no interest or value in having those newer technologies then they are irrelevant. Second, just because a system is superseded by changed business needs it does not follow that it cannot be updated. If it can be updated without undue risk and/or cost then we’re all happy; we see none of the characteristics of a legacy system. (If there are difficulties changing it then that’s another story.) In other words, it’s not about how the system is positioned today relative to external factors, it’s about how it can adapt to them.
Wikipedia’s definition is least helpful of all. Simply using legacy as a synonym for “old” doesn’t provide any practical benefit. As I said earlier, many systems are continually evolving at an acceptable rate, with acceptable risks, despite being old. They display none of the characteristics of legacy systems.
When I look back at the above characteristics of legacy systems I see a common theme of resisting change—hence my definition.
It’s also important to emphasise that all those characteristics are relative. They are relative to the observer’s expectations. For example, expectations of delivery time have increased in the last few years, which means “time-consuming to introduce new features” might be descriptive of a system today even if it took the same time to deliver the same features a decade ago on the same system.
“Skills shortage in the marketplace” could be true of COBOL, to pick one technology usually considered legacy. But if you’ve got a strong, dedicated team of COBOL developers then the lack of others in the marketplace isn’t a concern to you. Similarly risk is relative; degree of vendor support is relative; and so on.
Overall, “resisting change” is a relative term. If the rate at which your system changes is acceptable in your organisation then there’s no need to label it legacy. If one day a new CIO then arrives and resets expectations, suddenly it’s become a legacy system even though nothing else has changed, either in the marketplace or in the system itself.
To me, resisting change is the overarching characteristic of a legacy system. It doesn’t matter how old it is or what its inherent structure is or how much the outside world is moving on. What matters is whether it’s keeping up with us. It’s relative to our expectations. If we apply the label this way then I think we are all in much better position to improve our technology across the board.