Legacy software is code that has been around for a long time. It’s still useful, and fulfills ongoing needs, but the particular hardware it is tied to may have been updated, while the software lags behind. Other than being outdated, other issues may start to arise, such as lower efficiency, problems with compatibility or increasing maintenance costs. In fact, research from CAST Research Labs estimates that legacy code maintenance costs an average of $3.61 per line of code.
A legacy software application is “an information system that may be based on outdated technologies, but is critical to day-to-day operations.” ~Gartner
Updating legacy software is no simple feat, but nevertheless is one that many companies are facing right now as they modernize. According to a report from VMware and the MIT Technology Review, 62% of IT leaders say that the integration of legacy systems has been their biggest challenge in embracing multi-cloud strategy. As technology continues to advance, staying ahead of the competition requires new systems and growth.
That’s why we have put together a list of top tips for how to start modernizing your legacy software, one step at a time:
1. Evaluate the need
Before implementing any changes, it is important to take the time to understand the complexity of the software and underlying code, any risks involved, and what the biggest flaws are. This will allow for the risks to be better understood, and for the potential prioritisation of some updates over others.
2. Read all accompanying documentation or README files.
They often have information that will help you to understand the set up of the code base some more. You may also be able to determine the project history, given how the code has evolved over time.
3. Speak to a developer that worked on the code (if possible).
If the code has been around for a while, it may be that whoever worked on it is no longer on the project - but if they are, this is an opportunity not to be missed. They may be able to provide you with key insights, who the end users are, the context of some of the decisions made, answer some of your questions, and all in all, save you plenty of time.
4. Perform a static code analysis.
This will allow you to catch any red flags, or areas of the code that may lead, or are already leading, to potential problems. These can then be prioritized. It should also reveal the current test coverage on the code, and which code is dead, i.e., never used, and which is hot, i.e., called at every run. Together, this will inform you of the code architecture, frameworks, and pattern, to really understand the purpose of the code.
5. Identify duplicate code.
This will reveal whether there are redundant lines in the code base. Simian is a ‘Similarity Analyser’ that you can use.
6. Taking the first step is better than taking none at all
Some organizations will find that total transformation and enterprise-level system changes are a necessity to keep the company moving forward. The risks involved with this approach and the funding necessary mean that it doesn’t tend to be the most popular. No system change, on the other hand, carries a different set of risks, such as that of falling behind. One of the most popular approaches is the ‘duct tape approach’, as outlined by Cognizant, where localised, small changes are used to address the most pressing issues in the software legacy.
7. Identify use cases
You can do this by running the code. The end result should essentially provide you with the user requirements. This will determine what your final product will need to be able to achieve.
8. Take your time
Rushing will (more often than not) lead to bugs in the code. These bugs may be fine for the short-term, but the technical debt will pile up over the long run. Technical debt drags down productivity: a 2018 survey found that the average developer spends approximately 13.5 hours each week addressing technical debt. Consider the implications of any changes, and whether someone else could easily read and understand them. One useful technique is to learn how to use formal logic to prove what the outcomes of the code are. Some resources can be found here.
It’s important that large-scale and risky changes aren’t being made by a single engineer. Collaboration and frequent knowledge transfers between representatives of different teams within an organization allow for more efficient change in the long run, with various issues and suggestions likely being flagged earlier in the process.
10. Establish sufficient testing environments
Software refactoring will likely need even more testing environments than before, because the new versus old code behavior will be tested more frequently. Testing and comparing the two versions frequently brings clarity and certainty to each code commit. Document the modifications as you go, so that if the need arises, the code can easily be understood.
Legacy code can also be safely refactored with automatically generated unit tests, and you can find our guide to this here. Diffblue Cover will no doubt save you both time, and mental energy. Don’t just take our word for it though: using Diffblue Cover, Goldman Sachs doubled code coverage for one of their legacy applications from 36% to 72% in less than 10% of the time it would take to do manually. Read about it here.