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!