Developers are always looking for a shiny new toy but we spend most of our working lives working on “legacy software”. I’m glad to see Chris Birchall tackle this important subject. He notes that most programming books talk about new projects but we need the most help working with legacy software. Hence, “Re-Engineering Legacy Software” is a must read for any software developer. Below are my favorite highlights and what they mean to me.

First he defines legacy software as being:
- Old – a few years old, and often having a few iterations of team members cycling through the project.
- Large – successful software grows, often to the point of unwieldiness
- Inherited
- Poorly documented
Sound like any software you know?

Worse, legacy software introduces fear of change. It’s so hard to predict the impact of any new change that teams try to protect the status quo. (If it’s not broken, don’t change it.) Birchall writes that “Any change is seen purely as a risk, and the potential benefits of changes are ignored.” This contributes to a self-fulfilling prophecy – entropy wins, and the software keeps getting worse over time. I’ve seen this happen so many times and it’s always frustrating.
The pinnacle of this fear is assigned to “dangerous” areas of the code – those that are the least well understood, or buggiest, or most fragile, or other means. But rather than avoiding these sections of the code, Birchall suggests we run head-on into these sections. They are the areas needing the most help and our focus should be on improving them, not avoiding them. We should improve the software and leave it better than we found it.

Refactoring is the best method to chip away at an unwieldy system and make it manageable. While Birchall suggests some techniques individuals can use to refactor parts of a legacy system he makes it clear that refactoring is a team sport. Without buy-in from most or all of the team, any individual refactoring efforts may lose out to inertia, or burn-out the refactoring developer. His success stories are inspiring!
The other technique for taming legacy software is adding test automation. This presents challenges when the legacy code is inherently untestable. A chicken-and-egg problem appears – refactor or automate tests first? Sometimes you need a small refactoring to be able to add test automation. This is ok, there are no hard-and-fast rules, except to work in manageable pieces and have team buy-in.

Documentation is often out-of-date, Birchall has two key suggestions for keeping automation fresh:
- Documentation lives with the code: “README is the most important file in the repository”. It’s easy to update the documentation with the code when it can literally be done in the same Git workflow developers are already using for code changes.
- (Automated) tests are the documentation: The tests literally describe how the software works – how to setup, execute, and verify expected behavior. If the tests are out of date the software may fail to build!
At just over 200 pages this is a quick read that’s jam-packed with useful insights. Highly recommended to anyone building or maintaining software systems! Please check out Re-Engineering Legacy Software.