Michael Feathers, author of “Working Effectively with Legacy Code” defines legacy code as “code that we’ve gotten from someone else.” He goes on to define it as “tangled, unintelligible structure, code that you have to change but don’t really understand” and “difficult-to-change code” and even “legacy code is simply code without tests” because “With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don’t know if our code is getting better or worse.”
Regardless of your personal definition of legacy code, the question that usually bubbles to the surface is: “What should we do about this legacy code? Should we throw it away and rewrite it or should we leave the existing code and build on top of it?”
Whether you are a business owner who outsourced your software development and now wants to hand it over to someone else to improve/revise it, or a development team that has inherited code from someone else, here are some tips to help you make heads or tails of your situation.
Before you decide what to do, you have to take stock of your situation. Ask these four questions:
The answers to these questions directly impact how to go about dealing with your legacy code base.
Let’s walk through four examples:
Company A has been in business for 14 years. They have a thriving business, thousands of customers, and a reputation as a high quality brand. In 2014, they went through a rebranding, which included building a new software platform. After the rebranding effort was complete, the executive team discovered that while the visual elements of the rebrand were successful, the “behind the scenes” elements were not so successful. The result: a software platform in production that thousands of existing customers were seeing daily that threatened to ruin the brand’s reputation.
Company A Status Quo
Legacy Code Base Solution: Triage
For Company A, the solution is: Triage.
For a legacy code base situation like Company A, act as if you are in the Emergency Room. Your goal is to stabilize the code first. And your second priority is to invest in the future and implement tests, do refactoring, clean up technical debt. Resist the temptation to throw away the code and start over. That would take a lot longer and would leave production code with bugs in the hands of your customers. Also resist the urge to clean up tech debt first. Work on customer facing value-adds ASAP to get the product stable, and then assess. Add just enough automated tests to the system to make sure your new code works.
In a greenfield, or new code base, manual regression testing isn’t something we do. Instead, an automated test suite is built that can handle regression testing. However, manual regression testing, at least at first, is also important. Without a working test suite, expect bugs to be introduced, even into seemingly unrelated parts of the system. Having one or more people take on the “regression tester” role can help. Before each deploy to production, walking through the system in a staging environment can help lower the chance of introducing new bugs while fixing the old ones (the “whack-a-mole” problem).
In this case, the code is good enough to keep, and it’s built in a modern tech stack. So, it’s not necessary to migrate the code base to another tech stack or to rewrite it. In this scenario, Triage works best.
Company B is a startup. They have a big demo coming up in three weeks, and they haven’t yet launched their MVP, so they have no customers. The issue here is, they rushed and now realize the code quality is low. As a result, each time they go in to add a new feature in hopes that they’ll get it done for the demo, they break three other things.
Company B Status Quo
Legacy Code Base Solution: Intentional Technical Debt
Although the existing code is poor, there’s no time to rewrite it. Even if there was time, it wouldn’t be the way to go here. The goal is getting a working product ready for a demo. Someone that sees the demo isn’t going to look under the hood. Instead, they are going to make a decision to buy or invest in the product based on what they see in the demo.
So, the legacy solution here is to be very strategic about where to spend time:
Company C, like Company A, has been in business for over a decade. However, in this case, the code base is very old, and there is no “fire.” Instead, the company has been getting by with what they have, and there’s no immediate danger to the brand.
Company C Status Quo
Legacy Code Base Solution: Rewrite
For Company C, the choice is to throw away the legacy code and start from scratch. The code is so brittle and so old that it would be a more expensive endeavor to have a team go into the existing code and learn it enough to be able to make sense of it. In this case, the company is more than happy to use the existing, old product for another few months while the new one is being built.
The legacy application is used in parallel to the new application as features are rolled out. This has an added benefit that the end users can see two systems side-by-side to give very useful and real time feedback on the new application.
Company D has been in business for over 30 years. They have many systems, some home grown, some purchased, many integrated with one another, and all in various states of effectiveness. One software application was written in Rails 1.2 several years ago. The code had full test coverage and was high quality. After it was written, it was used and continues to be used daily. However, it hasn’t been touched since 2007.
Company D Status Quo
Legacy Code Base Solution: Upgrade
In the case of Company D, a very light-weight, two- to three-week upgrade is all this code needs. With some smart refactoring, an upgrade to the newest version of Rails is a simple chore. There’s absolutely no need to throw away the existing code or to be too heavy handed here. In this case, a light tough is the most cost-effective solution.
Each legacy code base scenario is unique. It’s difficult to decide whether or not to scrap a legacy code base that you’ve invested time and money into. On top of which, once you decide which path to take, you then must implement the decision. To learn what to expect along the way, read Top 4 Lessons Learned — What To Expect with Legacy Code Migrations
If you still have questions about the best way to handle your legacy code base, email me, I’m happy to walk through your situation with you and give some advice.