What Is Legacy Code: 8 Tips For Working Effectively With Legacy Code
Legacy code involves dealing with older code and code you didn't write can be a chore. But, unless you’re starting a project from scratch, it's inevitable. And that means you need a better way to work with legacy code.
That is why we have included guidance that explains what is legacy code, best practices for working effectively with legacy code, and how static code analysis can help with refactoring.
Read along or jump ahead to the section that interests you the most:
- What Is Legacy Code?
- Why Is Working Effectively With Legacy Code a Challenge?
- 8 Tips for Working With Legacy Code
- Tools for Working Effectively With Legacy Code
What Is Legacy Code?
Legacy code is source code inherited from someone else or inherited from an older version of the software. It can also be any code that you don’t understand and that’s difficult to change.
📕 Related Resource: Learn why working with inherited code is important for software quality.
Why Is Working Effectively With Legacy Code a Challenge?
The biggest challenge with working with older or unfamiliar code may be your assumptions about it.
You may think the code is bad. Whoever wrote it didn’t know what they were doing. You could have done a better job.
But the truth is, there's usually is a reason why the code is how it is. And, if you didn’t write it, you might not know that reason.
That’s why care needs to be taken when making improvements to the codebase. You can’t just put a quick fix on one area. There might be some dependencies you’re unaware of.
And that’s why it’s important to know when to maintain or to change it.
8 Tips for Working With Legacy Code
You can’t improve the inherited code overnight. But, you can take gradual steps to improve it.
Whether you’re just getting started — or you’ve been working on it for a while — here are eight tips that you should follow.
1. Test the Code
One way to understand the code is to create characterization tests and unit tests. You can also use a — like a static code analyzer — over your code to identify potential problems.
This will help you understand what the code actually does. And it will reveal any potentially problematic areas. Once you understand the code, you can make changes with greater confidence.
2. Review Documentation
Reviewing documentation of the original requirements will help you understand where the code came from.
Having that documentation handy will help you improve the code — without compromising the system. Without this information, you could accidentally make changes that introduce undesirable behavior.
3. Only Rewrite Code When It’s Necessary
Rewriting an inherited codebase can be tempting. But it’s usually a mistake.
It takes too much time and too many programmers to rewrite everything. And even if you do it, rewriting code can introduce new bugs. Or it can remove hidden functionality.
4. Try Refactoring Instead
It’s better to try refactoring legacy rather than rewrite it. And, it’s best to do it gradually.
Refactoring is the process of changing the structure of the code — without changing its functionality.
This cleans the code and makes it easier to understand. It also eliminates potential errors.
When refactoring code, it’s best to:
- Refactor code that has unit tests — so you know what you have.
- Start with the deepest point of your code — it will be easiest to refactor.
- Test after refactoring — to make sure you didn’t break anything.
- Have a safety net — e.g., — so you can revert to a previous build.
5. Make Changes in Different Review Cycles
Don’t make too many changes at once. It’s a bad idea to refactor in the same review cycle as functional changes.
Plus, this makes it easier for code reviews. Isolated changes are much more obvious to the reviewer than a sea of changes.
6. Collaborate With Other Developers
You may not know the codebase very well. But some of your fellow developers probably do. It’s much faster to ask questions from those who know the codebase best.
So, if it’s possible, collaborate with someone who knows it better than you do. A second set of eyes on the code may help you understand it better.
7. Keep New Code Clean
There’s a way to avoid making the code more problematic. And that’s by ensuring the new code is clean. It ought to be written to adhere to .
You can’t control the quality of the inherited code. But you can make sure that the code you add is clean.
8. Do Further Research
Working with an inherited codebase gets easier with time. A junior developer may not understand why a codebase hasn’t been refactored (and may be keen to refactor it). But a senior developer will know when to leave it alone.
Learning more about the codebase will help you improve it.
A good starting point is this article by Michael C. Feathers, which contains some good examples of how to make changes to the codebase.
Another good source is “” by Martin Fowler. This book offers many tips for effectively refactoring code.
Tools for Working Effectively With Legacy Code
You’ll always need to work with inherited code — or work around it. After all, the code is there for a reason. It works. And its results may be good enough that you can let known issues go.
There are good reasons for making changes to code, too. You might be adding a feature, fixing a bug, or improving the design.
In a perfect world, you’d continually rewrite that older or unfamiliar code until it’s fully debugged. But chances are, that won’t be practical.
So, what you need to do is figure out what you can change — and leave the rest alone.
Static Code Analysis
One way to do this is by using a like a static code analysis tool. You can set a baseline and then run an analysis on the new code to make sure it’s clean. And you can suppress results from your codebase.
Klocwork, for example, make this very easy to do. and
Analyze Legacy Code
Helix QAC can check your codebase against rules, typically from a . You’ll get diagnostics of violations. And you can prioritize them by severity. This means you can focus your attention on fixing the most error-riddled pieces first.
You can also set your codebase as a baseline. Maybe the code is fine as-is, and you want to leave it alone. Setting a baseline means that the codebase won’t be pulled into your diagnostics. Instead, you can focus on finding issues in new code — and ensuring that’s clean.
You can also use suppressions to create exceptions for your codebase. So, you can essentially dismiss violations in it. You might set your suppressions on specific rules or violations within a particular category.