Refactoring means, in simplest possible terms, improving existing code without changing its functionality. It’s all about code quality and optimisation, not product redesign. Users never see the changes. So why do it? Because ultimately, refactoring can prevent your app from generating huge upkeep costs and, as a result, make your business more successful.
The basic aim behind refactoring is as follows: to fix problems in the code but keep its current functionality. You modify and restructure what you or other developers on the team have written, but the product stays more or less the same. Refactoring is not about improving users’ interactions with the product - it's about the developers’ interactions with the codebase. Refactoring makes the code more readable to the current (and, importantly, future) developers working on it. It’s then easier – and cheaper – for them to continue developing and maintaining the product.
A ‘refactor’ means a single change in the code. To make or do a refactor means to introduce a particular fix which, in accordance with the above definition, enhances the code’s quality. Here are some extra reasons to do it, if you weren’t convinced already.
If you think about it, making errors when coding is inevitable. Maybe there are geniuses out there who always write clean and flawless code, but if so, they are rare. You can’t expect super-human performance from your development team, and you have to accept that their mistakes will be part and parcel of the development process.
Just like refactoring, fixing those mistakes is a part of the process.
If you see a code fragment that could have been written better, improve it. Immediately. If you don’t do it often enough, your product will suffer as current risks lead to future problems.
Refactoring helps developers understand how the product works and what it’s supposed to do. They are more engaged in the project, can easily delegate tasks to other developers (who should now have no trouble reading and working with more understandable code), and can take full advantage of others’ work thanks to, for instance, clearer methods. It’s best to put everything a developer needs to know into the code, so comments and remembering a lot of information become unnecessary.
Clean code means that developers can easily see which fragments hold the most business value. Actually, clean code means developers can more easily spot separate elements in the code. You might think it should be obvious from the beginning which functionalities will matter most, but that’s a fallacy. It’s something you need to learn anew for every product you work on, because every product is different.
Projects get really expensive when you need to fix legacy code months or years down the line. With regular refactoring, developers find bugs more easily, which means a smaller QA budget and fewer hours spent on scrutinising the code by developers themselves. There will be no need to constantly go back and fix something that has become a blocker. By preventing problems from occurring rather than reacting to them, you will be able to achieve faster development. And obviously, the development work is the most expensive part of building a digital product.
Martin Fowler is a proponent of refactoring, and he knows what he’s talking about, because he’s been doing this for years. Fowler and other experts agree that building a product without any refactoring is a massive risk. Here, have some quotes:
All right, now that we’ve established that your project needs regular refactoring, how should you go about it?
Before you even start thinking about it, make sure the code under scrutiny has been tested. Extensively. Never refactor before you’ve written tests, that’s just asking for trouble. I mean it. Never. If you have no tests, write them. Then come back to the idea of refactoring.
Here’s a list of warning signs that almost always mean that particular fragment of code needs a refactor and some basic guidelines on what you can do with them:
As a Ruby on Rails consulting company we use RoR a lot, so we’ve picked up a few tricks over the years and are always happy to share our knowledge. (On our blog, you can read articles about service objects, writing good code and being a better developer, and many other subjects)
Refactoring is a wonderful tool, as long as it’s done well. In some situations and without the necessary experience, it may do more harm than good. If you aren’t sure that refactoring will bring business value to your product, don’t do it.
Stakeholders will naturally view refactoring as a waste of time. They will usually be wrong, but it’s important for the product owner to establish what’s most important for the project at any given time. Should we focus on time to market or future refactoring debt? The latter may seem like a problem that can be taken care of later, but many people who have thought so, have suffered by adopting this approach.
Finally, refactoring should always have a clear goal: improving the code behind one functionality. If it’s about a very general value, such as efficiency, you will simply never reach your goal. It’s too big a task for a single refactor, and it can be a waste of resources. Moreover, without a clearly defined goal, you won’t even be able to tell whether you’ve achieved it or not.
We’ve witnessed refactors doing wonders for projects, and we’ve witnessed refactors going really, really wrong. One example of the former is a project that involved generating reports from questionnaires. It used a really old gem that had had no support for 6 years. It took care of the whole functionality, but seriously complicated the code, which means that adding features to the product was pretty much a heroic feat. And expensive. We talked to the client and did a refactor, which resulted in dumping the prehistoric gem and building a custom solution with the same functionality. The database shrank from 15 to only 2 tables, a critical component of the app started working more quickly, and the behaviour of the whole product became more predictable. The code was, of course, easier and cheaper to maintain and develop further.
A less cheerful example is a client who wanted a refactoring for its own sake. The whole process wasn’t well thought out, we had too little information and instead of completing the refactor in 3 months, as we estimated, we laboured over it for half a year. During that time, no new code was produced, which obviously set the project back quite a bit. Eventually, we managed to get the development work going at full speed and the project is doing quite well, but doing the refactor was a waste of time and resources.
These stories show you that, while refactoring is crucial and should be an integral part of your process, there must a time and place for it. Refactoring comes with a risk that can be mitigated by an experienced team. So, if you are thinking about refactoring your project, feel free to contact us about any questions or doubts you might have, and we will be happy to share our knowledge and experience with you.