- Read Tutorial
- Watch Guide Video
It’s one of the dirty little secrets in the freelance world that a high percentage of the projects that you’ll be asked to work on are actually legacy applications, which means that you’ll be taking over or working with other developers on pre-existing apps.
There have been a number of times where I’ve had great experiences taking over a legacy application. Notably I was hired a few years ago to work on a legacy app for Eventbrite and I was very pleased to find a very well configured codebase. It only took me about a week to become familiar with the inner workings of the application and I was able to start building new features right away, it was a great experience. However that rarely occurs, typically freelancers are taking over a legacy application because the previous developer was fired from the project or due to the app owner having issues with the performance of the software.
As a case study, a few years ago I was asked to become the lead developer for a legacy Rails application that had been around for a while and already had multiple developers (which is already a bit of a red flag since well written applications are typically much easier to maintain and therefore the original developers are usually still around in some fashion or another). To put it nicely the app code was convoluted and even after a year it was still difficult to add new features. The legacy code was so fragile that one change could have a domino effect and break other features, with a number of the bugs not showing up until weeks later. Needless to say the situation was a mess.
I was explaining my predicament to a good friend of mine who was a pretty experienced developer and he recommended I read “Working Effectively with Legacy Code” by Michael Feathers. Thankfully I was able to take what I learned in that book to help completely revamp the application that I had been having issues with.
Tips for Taking Over a Legacy Application
Creating a Test Suite
While there are a number of techniques you need to apply in order to work with a legacy application, the first should be building a comprehensive test suite. No matter what language or framework that you work in, you will be able to create automated tests that capture the functionality of the application.
So in the legacy application I was working on I started creating tests for each model. I began with basic unit tests and then started branching out to integration tests that ensured that the various elements of the codebase were communicating properly with each other. Going through this process had the added bonus that I became more familiar with the structure of the app and I was able to refactor the code as I implemented the tests.
Add New Features via TDD
Once the test suite was built I started building all new features via the TDD (test driven development) method, which ensured that the test suite was up to date. By utilizing this process, it also made it possible to ensure that the new features that I added wouldn’t break pre-existing functionality, this is called regression testing.
Break Out Specific Features into Microservices
The further I got into the codebase I started to notice that the app had become bloated with features and many of the components didn’t need to be included in the core application. Therefore I slowly started creating microservice applications that handled isolated pieces of functionality. Some examples were: creating a microservice that managed the user notification system and building an app that processed the reporting engine. After creating the microservices I was able to get rid of significant portions of the legacy code and then simply wire up the legacy application with the new microservices so they communicated properly.
DRYing up the Codebase
In many legacy applications you’ll run into duplicate code which causes a number of problems, including the issue of having to make one change in multiple places in the codebase. An example of this was how the application I was working on dealt with view templates. There were a number of view files with identical HTML code. I was able to refactor these components into partials that could be shared across the application, which allowed me to make a single code change that would populate throughout the app.
The topic of taking over a legacy application is important to understand, not only for the reason of being prepared for what steps you need to take in order to work on a legacy app, but also so you will have a better idea of how to build applications from scratch. Remembering back to the Eventbrite application that I mentioned earlier, that application was easy to work with and add features to namely because it had been built from day one using each of the techniques mentioned in this guide.
If you develop an application from scratch using these best of breed techniques you will make it easier on yourself when you’re adding features in the future. It will have the added benefit that any new developers that may work on the application in the future will be able to start adding new features easily and they’ll appreciate the extra work you put into the development process.
I hope that this has been a helpful guide for taking over a legacy application and that you can apply it on the projects that you’re working on.