In 30 seconds
- Legacy code is often defined as code without tests.
- Add characterization tests before changing anything.
- Change in small steps; replace big parts gradually.
The approach
- Find the change point.
- Write characterization tests that capture current behaviour.
- Break dependencies at seams so code can be tested.
- Make the change and refactor in small steps.
Michael Feathers set this out in Working Effectively with Legacy Code (2004).
The strangler fig pattern
To replace a large old system, build new pieces around it and route traffic to them one by one, until the old system can be removed. Martin Fowler named the pattern after the vine that slowly surrounds a tree.
Avoiding big rewrites
Full rewrites take longer than expected and often recreate old bugs and technical debt. Incremental improvement delivers value along the way and keeps risk low.
Myth vs reality
The AI angle
AI is useful for explaining old code and drafting characterization tests, which are often the slowest steps in legacy work. Review its explanations; they can sound confident and be wrong.
FAQ
What's a characterization test?
A test recording what code currently does, right or wrong.
What's a seam?
A place where behaviour can be changed without editing the code there.
Should we stop features to fix legacy code?
Usually no; improve code as you work in it.