Moving Forward From Legacy Systems
Upgrading and updating older applications can leave developers frazzled and stressed. But the end result is worth every bit. Maintaining legacy code forever isn’t just bad for developers’ health—it will slowly sink a business as more competitive, agile systems compete. Are you migrating to newer versions like PHP5 to PHP7, refactoring codebase, or moving to a completely new system? Create a plan to fix your legacy codebase.
“If it works, why touch it?”
As a long-time developer house, much of what we do is battle the monsters of legacy systems.
While that may not seem very glamorous, the horror stories about maintaining legacy code can be a bit overblown. Wrangling old codebase isn’t an exact science, but lots of experience has given us an edge in dealing with legacy issues.
We’ll walk you through how to think about an upgrade, refactor, or migration project to your codebase. By the end of this article, you’ll have a step-by-step plan to move away from the legacy system.
What Is ‘Legacy Code’ and Why Is It Challenging to Deal With?
Think of legacy code like teaching older people how to use modern digital technologies. It’s not very efficient and newer versions can be difficult for them to comprehend quickly. Legacy code often can’t do what newer versions offer, and if a business case requires an update, that legacy code has to work a lot harder to achieve the same result.
Many companies operate just ‘fine’ on legacy systems and do so for a variety of reasons. But legacy code is a slow-moving problem. Often, these problems are inherited—the people that built them aren’t involved anymore, and the people who inherit the project are usually lost when it falls into their lap. This scenario causes unsupervised growth, where every new developer adds something to the project, adding on workarounds until it becomes a monstrous mess.
This process of coding also creates technical debt—a hidden cost that undermines an organization by making their codebase work against them. Investing in a sustainable, long-term solution pays off in the end, while a bunch of quick fixes that work ‘the easy way’ will accrue errors and issues until it eventually falls apart.
Legacy code can also just refer to older platforms which don’t support new features, which means companies can’t plan ahead to meet future demands.
What Are The Symptoms of a Legacy Codebase?
If your codebase experiences one or more of the following symptoms, it’s probably time to refactor, update and get out of your legacy problems:
- Developer wasteland. Legacy projects require skill sets that are expensive and hard to find. Getting stuck with legacy code that will forever be in ‘maintenance mode’ is a developer’s worst nightmare, which then leads to higher churn rates.
- More bugs appear as new functionalities are added, often because they’re coupled with legacy code which leads to a cycle of fixing bugs that generate new bugs.
- Agility losses lead to slower time-to-production, as your developers battle zombie appendages, rather than developing within a codebase that can adapt on the fly.
- “Don’t touch the legacy code” is spoken by one or more of your peers, or in your internal dialogue when coding.
- The hidden costs of legacy code are becoming more apparent. IT maintenance research shows software maintenance accounts for more than half of the overall development budget for projects with over 500k lines of code.
- Legacy Infrastructure and IT costs exponentially rising over time as every update adds more parts to the system, causing longer maintenance windows.
Why Refactor At All? The Big Prizes
You’re probably already aware if you’re working on a legacy project. It can start to feel hopeless, so what’s it all for? How do you convince stakeholders, project managers, product owners, business analysts and clients that refactoring is valuable?
- Resource Efficiency.
Proper refactoring ultimately leads to delivering modern, powerful features with ease, investing small periods of time which ultimately lead to gains in weeks or months where your developer resources aren’t wasted slogging through bad code.
- Lower cost of maintenance.
The cost savings associated with refactoring are significant. If you can’t take our word for it, just look at Badoo, which saved one million dollars updating to PHP 7 from their legacy system running PHP 5.
- Balancing maintenance and microtasks.
Most refactoring tasks are small in scale, allowing your team to simultaneously maintain critical systems, while slowly improving the codebase. With this method, risk is kept low and incremental gains are made to clean out the codebase.
What About A Rewrite From Scratch?
Like chasing a mirage in the desert, rewriting your codebase from scratch is usually never recommended. There’s a strong argument somewhere for why your developers kept that legacy system intact. Legacy code should also never be discarded altogether—there is valuable knowledge even in older code, and usually some of it is still usable.
In the worst case scenario, a complete rewrite can lead to doubling workload and bugs! If you weren’t happy fixing a legacy system before, now you’re also stacking an entirely new version on top of that!
Peek Into A Typical Refactoring Process
Now it’s time to plan and strategize your refactoring process. In our webinar series on getting a handle on legacy code (registration form below), we go into this process in greater detail, but for now we’ll just cover the big points.
- Step 1. Start with your plan.
Refactoring is an iterative process that will occur over a significant period of time, so plot out goals for where you want your app (and business) to be weeks, months and a year in advance.
- Step 2. Note your bottlenecks.
List out every architectural roadblock that prevents you from meeting those requirements.
- Step 3. Cut out your unused and least-popular features.
The goal here is to minimize the scope of code that you have to refactor during the process. Prioritize things that matter!
- Step 4. Consolidate your refactoring goals.
Now that you’ve laid out individual goals and how to achieve them, group together as many parallel projects as possible.
- Step 5. Plan your architecture and write tests.
Mark critical paths in your application. start with those functionalities. functional testing (e2e are better in that case if you don’t have tests)
- Step 6. Create new interfaces.
Based on new architecture and Isolate the legacy codebase with proxy code. Run tests to make sure we didn’t break anything
- Step 7. Avoid software rot in the future.
Document your code, technical debt, and architectural decisions with reasoning. This will help any newcomers to the project get onboard quickly and keep you on track towards your goals.
As refactoring continues, your workflow for the entire process will be defined. Functional tests will run on as planned, and the deployment process will feel a lot easier.
To achieve this task, it’s good to have a technical partner who has experience in dealing with legacy systems to help you make technical decisions based on your business needs.
Want to learn more?
Click HERE to watch my webinar
on moving forward from legacy systems