We recently spent a few days on a new project on refactoring the existing codebase. Refactoring involves altering the code’s internal structure, but without changing the outward appearance or functionality, it’s difficult to convey the benefits and show the results to our clients.

Justification for refactoring seems to be less tangible than test coverage, because many see their apps as “if it works, why touch it?”. But there are many advantages to dedicating time for refactoring, including saving time and money further down the line.

As an agile team, we are continuously maintaining and extending our code from iteration to iteration, as refactoring is valuable to prevent “code smell”. Code Smell is any symptom in the source code of a program that possibly indicates a deeper problem. It can take several forms: unhealthy dependencies between classes, bad allocation of class responsibilities, duplicate code, and many other varieties of confusion and clutter.

If we were to change code without refactoring it, the smell would worsen and spread. That frustrates us, costs us time and the client money. In an agile context, it can mean the difference between meeting or not meeting an iteration deadline.

If you think of refactoring as cleaning a kitchen as you cook. As you prepare food throughout the day, you’ll typically find that cleaning and reorganising occur continuously. Without this, continuous cooking would soon collapse! Messy dishes that would typically take 5 seconds to clean straight away can result in 10 minutes of aggressive scrubbing if left.

When we are faced with a new project that already has an extensive codebase, we always focus our efforts within the first few days on refactoring as part of our discovery phase. There are several reasons why:

1. Making code readable for the next developer (or your future-self!)

Having to translate someone else’s code can be overwhelming. Having a manageable and well-structured codebase will prevent confusion for any future developers.

2. Keeping the codebase maintainable and upgradeable

Integration of updates and upgrades is a continuous process that is unavoidable and should be welcomed. When the codebase is disorganised and built on a flimsy foundation, developers are often hesitant to make certain changes. But with refactored and organised code, the product is built on a clean foundation for further updates.

3. Investing in development time

Code refactoring is most often thought of as something performed by and for programmers, but ultimately it is a business decision. Refactoring is a big time commitment which begs the question “Is it worth it?”. There is a cost and time trade-off involved. The immediate feature could be done and dusted in a day, or another half a day could be added to improve the code we’re interacting with. There is a gamble that delaying feature development a little bit is worthwhile because the likelihood of future features will be done quicker.

4. Automated testing

Refactoring will inevitably lead to new bugs. To prevent that, there needs to be complete coverage of automated test cases. Manual testing just won’t cut it – it can be cumbersome for the refactoring and it takes a lot of effort and patience to manually test every time after changing the code. So, before starting refactoring, having written enough test cases will ensure the code functionality works!

So how do we show the outcome of our refactoring?

This is a tricky one. When refactoring happens as we go along and develop new features, it’s very difficult to show (in non-technical terms) just exactly what has been done. However, if your refactoring involves simplifying the codebase and reducing duplication, we use a command line tool to generate a visual plan of the structure. Doing this before and after the refactoring can help to display the changes in an easy-to-understand way (I certainly found it helpful!)

Here’s an example of the most recent refactoring we did:

Before

After

As you can see, the code is much more simplified and organised. Our main task involved making the code DRYer by removing duplications. The database was refactored by creating new tables and columns to ensure it was normalised. After, we updated the models to reflect these new changes and made sure the controllers and view calls our newly updated methods, so all features are the same.

Conclusion

It’s true, refactoring doesn’t change the outward behaviour of an application. It doesn’t include fixing bugs or improving performance or robustness. Refactoring is simply about improving the design of the code, while ensuring that it still works the same. It might not seem valuable in terms of business value – your business won’t immediately get better once refactoring is done. Many realise the importance of refactoring for business when it has mitigated into a huge problem. But refactoring is a long-term view for business value and there is a huge potential for value loss in not doing it. The value of refactoring is exclusively contained in the future ability of programmers to comprehend and modify the code. Well-factored code is agile code and it’s mandatory for us – it’s much easier to change and add features in the true agile way so we always encourage our clients to embrace it.