Dealing with legacy code – the bane of our existence

Unless you are really, and I mean really, lucky, you are bound to be stuck on a legacy project with a thousand-year-old codebase. Maybe not a thousand years, but close enough. If it’s any like the code I have been working on, it’s big, really big, it’s complicated, no one really understands how it fully works, and it’s riddled with anti-patterns. What to do?

Burn it to the ground and start fresh

So, delete the codebase and re-write everything in a nicer language, with design patterns and all the bells and whistles.
Phew, that was easy, we didn’t we do that from the beginning?! Problem solved! Let’s get back to checking Reddit now!

Getting back to earth

OK, so burning everything might not be a sensible solution. More often than not the code took years upon years to write and is worth a small fortune. The client is not just going to let you throw that all away and sit tight while you are starting again from scratch. You’re in a bit of a pickle, you can’t live with the code and you cannot get rid of it. What to do ?!

The only sensible solution at this point is to slowly improve the codebase. It’s a slow and time-consuming process, so don’t expect your life to improve overnight. We now have a plan, let’s see how we go about putting it into action ?

Test it, test it, then test it some more

You will need to improve the code in the future, however, it’s really hard to do that when you’re unsure if you have broken it. This is where tests come in. Unit tests, integration tests, performance tests, you name it, you probably need it. The more tests you have, the more confidence you have that the changes you made are not breaking anything. In addition to that, writing tests help you better understand what the code is doing. Hooray for you!

Isolate and control access to the old world

The plan here is to control access to the old code as tightly as possible. You can do that with nicely designed interfaces and wrapper classes. Here where the tests we previously talked about come into place. Once you know you’re not breaking functionality, then you are in a position to do some serious refactoring. Every new functionality you add should use one of the nice interfaces. If there are none, add them! If it suits your project, you can turn the old world into a web interface that can be safely isolated from the shiny new code you are adding.

Slowly retire the old world

Since the legacy code is now contained and you can control access to that dusty old thing, as time goes by you can gradually remove the calls to it. Once there are no more calls, that is when you are ready to remove that chunk of code. Do that over time and the big monolith you begin with is starting to look smaller and smaller. You may not be able to fully retire the whole legacy piece of code, but you can at least save your team the trouble of always having to work with it.

Slow and steady wins the race

I must warn you, this is NOT a quick process. Depending the size of the legacy code it may very well take years to make a dent on the original codebase. You need to exercise patience. The motto for the whole process should be Leave the code better than you have found it. You may be tempted, especially when the deadlines are tight, to cut corners and go for the easy, messy solution. Do not do that!! I’m saying it again: Do. Not. Do. That. This is how we got that big mess we started with. You cannot solve a problem by doing the same thing that caused the damn thing in the first place!


How to deal with issues in production – the short version

Okay, imagine the following scenario: You’re happily going about your day, coding away, without a worry in the world, and then this hits you: “There is something wrong with the production app” (well, maybe not this exact message, but you get the idea). What do you do?! How do you go about fixing the problem and go back to your everyday life?

1. Calm down

Yes, things are bad at the moment. However, this is not the time to lose your head and run around with your hair on fire. You need to have a clear mind in order to focus on the problem and easily find the solution. Go to your happy place and come back when you are ready to get to work.

2. Calm down some more

If you are anything like me then you probably are not calm enough to think clearly. You should calm down some more.

3. Investigate the issue and understand it

OK, now we are ready to start doing something about the problem. The first step is to understand the root cause of the issue. Maybe someone deployed something they shouldn’t have, maybe the data became corrupted or maybe, and this only happens once in a blue moon, maybe there this is just a misunderstanding and there is no issue at all, in which case: Congratulations, you solved it.

At the end of this stage you should be able to at least answer the following question: When exactly does this happens ? 

4. Estimate the impact

Now that we know when the issue occurs, we can start thinking about who does this issue affect. A quick and dirty estimation should be enough. Some useful classifications are: critical (everyone is affected and everything is broken), medium (there is some impact, but the project will probably survive), low (this issue affects only a handful of clients/users), minimal (yes, there is an issue, but unless someone looks really, really hard they’re going to miss it).

Based on the impact of the issue you need to decide if you should fix this now, or later.

At the end of this stage you should be able to at least answer the following question: How bad is it ?

5. Calm down some more

OK, things are starting to clear up a bit now. You know what the problem is and how bad it is. Take a deep breath, decide when this needs to be fixed: either now or later.

6. Track down when the issue was introduced

If you use a versioning system (if you don’t you really, really should), use that to track down the commit that caused the issue. Look trough the code and use a sandbox environment (if any available) to figure that out.

At the end of this stage you should be able to answer the following question: What is the exact cause of the issue ?

7. Fix the issue

Now that you know what causes the issue you are in the best position to start fixing it, so go do it, be a hero and save the day.

Congratulations!! You fixed it!  You can go back to your happy life – crisis averted.