As an organisation grows, so does its software. New features are layered on top of old, and systems become composites of code written by lots of different people. When the people and coding languages inevitably move on, the next generation of developers must approach the legacy code without causing problems in the wider system.
Legacy code might come loaded with negative connotations, but it contains within it functionality and business knowledge that is hugely valuable. Rewriting systems is rarely an option so updating legacy code to add or improve functionality is part and parcel of systems development.
We discussed the challenges of legacy code with Dr Robert Chatley, Director, Software Engineering Practice at Imperial College London and co-author of The Next 7000 Programming Languages.
Why are there so many programming languages, and what cause them to evolve or go extinct?
People create them to solve problems, because they want to be able to express things better or with more confidence. New languages can die out very quickly because no one uses them. But once people start to use a language, then the code exists and people need to work with it. Take a language like PHP, for example, which was very popular in the 1990s and 2000s, you probably wouldn’t start a new project in that language now, but most of Facebook is written in it, so it’s going to exist for a long time.
It’s also a big ecosystem – people get jobs based on the languages that they know and what’s popular in the market. If you’re founding a company and you want to build some software, it’s worthwhile building it in a language where there’s a good supply of people who know the language, for instance Java.
But then it’s harder for minority languages, even if they are technically better, to take root. That’s why we have a lot of things that are written in legacy languages. Things don’t die out as actively as you might think.
When is it worth the investment of time and risk to rewrite code?
Generally it’s too expensive to rewrite because you’ve spent so much time building the system in the first place and there’s so much information encoded in it about how the business processes work. If you throw it away and do it again, it’s not just the time it takes to rewrite the code for the new system. You also have to go through all the thinking that got you to where you were.
But if the system is quite small, then you may be in a better position to rewrite. The current trend is to make systems that are composed of many small systems together, rather than big systems. Breaking things down into smaller pieces helps make them individually interchangeable, we call that microservices. When you make small things it’s easier to just throw it away and make a new one. But if you had a whole system to rewrite it would take too long and you would miss out on all the growth because you would effectively be going back to square one.
There are reasons why you might rewrite a particular piece of a bigger system – like it was originally written in a language that is now too slow. So you’re not able to process enough videos in the same time as you could using a newer language, for example. Then you can cut out that segment to rewrite. But in general, doing gradual improvements and refactoring – so not changing what a segment does but how it’s structured – is more tenable.
What is the best practice approach for dealing with legacy code?
If you find a section that is old and isn’t very well structured, but it works, just leave it alone. The bits you work with all the time – that you need to be really flexible and well-structured because they’re where you’re doing all your work – they are the bits you might want to target to improve.
Refactoring is a thing that you should do little and often. One of the things that often comes up is someone says, we’ve got into a terrible state, we need to have a three-month project to refactor to improve. It’s always quite difficult to sell that project in the business because what you’re saying is, we’re going to make the system do exactly what it’s doing now, you won’t see any differences but the code will be better, so when you ask for things in three months’ time we’ll be able to deliver them more quickly.
It’s a difficult conversation to have because in the meantime you’re saying that for three months you’re not going to be able to deliver any new features. Whereas if, whenever you do a bit of work, you do a little a bit of improvement at the same time, then you don’t need to have that discussion.
The other best practice tip is about testing. One of the things you want to do whether you’re refactoring or rewriting is to be sure that when you change the system you don’t break anything. With newer systems, current industry best practice is to write lots of tests as you write the system. Most systems that are built nowadays have automated tests – I can press a button and it will run tests that check that everything is working – but it wasn’t such a common practice 20 years ago.
So if you work on an old system, one of the things that we would recommend is to spend some time building up a suite of tests so that you feel more confident about making changes. Otherwise you change one part and something somewhere else stops behaving correctly.
If we can put the tests in place it gives us confidence to be able to go faster. But not everyone is doing that. Some people think doing all this testing is too expensive and it’s not worth the benefit.
Is there anything developers can do to futureproof their code?
Just the continual refactoring, so that you’re gradually cleaning up and then you’re not laying a trap for people in the future. It’s trying to be a good citizen and not just rushing to deliver the feature without thinking about those things. It’s developing good habits among people and a vision of what might happen if we didn’t pay attention to the craft of what we’re doing.
We’ve been assisting businesses with their Development needs and helping Developers find the right jobs since 1986. Read more about our Software Development and Test practice or get in touch if you think we could help.