Table of Contents
A while ago, we spoke about the main steps of introducing code refactoring to your project. Today we’d like to talk about the best practices for code refactoring and also highlight the main benefits the process brings. Since code refactoring may take quite some time, many teams sacrifice it for the sake of other tasks. As a result, technical debt keeps getting bigger and the project becomes messier. Code refactoring is one of the best ways to avoid these issues, but only if done right.
A quick overview of code refactoring
Even though we already defined code refactoring in the past article, let’s go through it once again. Code refactoring is a process aimed at cleaning the messy code and changing its structure without impacting its behavior and functionality. In other words, it’s a process aimed at obtaining clean code with simple design.
In some cases though, you might need to rewrite the whole code from scratch – this is what we call rewriting so don’t confuse it with refactoring. While refactoring is like general maintenance, rewriting is more like a resuscitation for your app.
You should have a pretty solid understanding of refactoring by now so we can move on to the question of when (and when not) to refactor.
When to and when not to refactor
One of the most common issues for a software team is code rot. Code rot encompasses duplicates, tons of patches, poor classifications, and similar issues that result from sloppy coding or from different coding styles coming together in one application. Also, don’t forget about code smells, which are indicators of poor programming. It’s important not to confuse code smells with bugs: a code smell is not a mistake, but rather a characteristic of a possible issue.
Code refactoring helps efficiently combat these issues since it’s aimed directly at improving the structure and maintainability of code without affecting its behavior. And since it sounds so great, you may think you need to refactor all the time. Wrong.
There are several rules when it comes to code refactoring timing. Let’s have a look at them.
When to perform code refactoring
Since code refactoring can be called code maintenance, you’d want to do it from time to time. However, you cannot just go in there and start refactoring since wrong timing can harm your project. Here is when you should do refactoring:
- When the performance goes low and you can see the processes slowing down.
- When you see the same errors happening over and over again and debugging does not help.
- When doing something for the third time (rule of three, graciously defined by the Refactoring Guru). After you do something for the first time, repeat the exact process for the second time and then refactor when it comes to the third time.
- Before adding any new features – we’ll talk about this point in more detail below.
- When implementing changes that were suggested during the code review.
- After delivering the product to the market since you’ll have enough time to take a break and refactor without any hurry.
When not to refactor
We had a look at situations that call for refactoring – now let’s look at the opposite ones. So when should you hold back and leave everything as it is?
- When you don’t have enough time or budget for refactoring – yes, it’s a frequent case.
- The code works fine and there are no security issues with it.
- During the implementation of new features.
A quick note on the last case. In the real world, refactoring is often performed in parallel with the implementation of new features. However, there is one critical condition here: new features must be isolated from old (existing) ones. As well, the team size should allow for simultaneous refactoring and adding new features: there should be separate teams working on each task. And obviously, you should have really well-organized processes if you want to combine code refactoring with adding any new functionality.
Code refactoring best practices
Even though refactoring, without a doubt, helps improve the quality of your code, in some cases you may skip the procedure. Now that we are clear on when and when not to refactor, let’s dig into the best practices of code refactoring that might help you better organize the process and ensure refactoring does not interfere with feature development and product launch.
Refactor before implementing new features
We’ve already mentioned that you should not do refactoring during the implementation of new functionality and now is the best time to explain why.
First, you don’t want to pile up new features over the messy code. Hence, it’s always a good idea to first refactor the code, improve it, and only then add something new. Second, separation of refactoring and implementation of new functionality reduces technical debt since you apply changes to the clean code. Third, performing refactoring apart from adding new features also reduces risks and troubleshooting simply because you do not make a mess out of dirty code and new features.
Consider deadlines and timeline of the project
We’ve already stated that refactoring is important and highly beneficial – but it may happen that you simply don’t have time for it. This is a frequent case for projects with tight deadlines where you can’t afford to spend extra time on code maintenance and refurbishment.
Therefore, before planning to refactor, consider the project timeline and deadlines first. Can you really step back and spend some time on improving the working code and do you need it in the first place? In some cases, code refactoring indeed makes a significant contribution to project performance so you need to analyze the consequences first. And don’t forget that refactoring may be quite costly so you might want to consider this factor as well.
Implement coding standards and ensure everyone understands the code
When different people work on the same project, chances are high that they have different coding styles. This may lead not only to the code becoming unreadable but also to performance issues in the future. Hence, to prevent any complications and to ensure the code (or most of its part) remains clean and clear, it will be a good idea to introduce coding standards for everyone on the development team to follow. In this way, most of the code will be written in the same way regardless of the person responsible for coding.
By maintaining proper documentation, you can unify the development, spend less time on code review, and minimize the number of potential issues in the future. As well, make sure everyone on the team actually understands the code, including all its sensitive areas like sensitive routines or variables. If you know the code inside out, it will be harder to mess it up so all team members should understand perfectly how things function.
Focus on eliminating duplications
Duplications are often the main reason for a messy code and once you focus on duplications during the refactoring, you’d be amazed at the code quality afterward. So why duplications? There are several main reasons why duplicate functions negatively impact the quality of the code:
- Duplications make the code more complex and cumbersome. This, in turn, has consequences during the debugging and testing.
- Duplications waste system resources by expanding the app’s size.
- Duplications call for making changes to all routines, not just one which, in turn, adds complexity to the development process.
Therefore, if you focus on battling duplications, you can significantly improve the code without going too deep into its refurbishment. That also means easier refactoring!
Leave comments in the backlog
This piece of advice may seem minor but it can make a big difference. When developers detect a code smell or know there is a complexity that needs to be fixed, they can simply create a ticket in the backlog. Such comments may include an approximate deadline for fixing the issue as well as an explanation of the complexity. In this way, backlog comments will serve as reminders and will help track down the problem source and fix it.
Refactor regularly
Finally, make refactoring a habit. Think of it as housekeeping: you don’t have to do it every day (or even every week) but it’s nice to have if not a schedule then at least some consistency. Just consider the project milestones and deadlines and plan refactoring correspondingly.
Expert Opinion
Refactoring is an integral and important part of the continuous development process. If you have a popular, high-demand application, it will be constantly changing and adapting to the users’ requests in order to remain competitive. Hence, a properly organized refactoring process can allow easy app scaling in the future as well as it can help fix existing issues. I can compare refactoring to an update of a vehicle model range. Same as when the car goes through updates and innovations, an application becomes more advanced and efficient with every new version, and refactoring plays a big role in the process of its optimization.
Frontend Engineer at SoftTeco
Sergey Obodovsky
Bonus: code refactoring KPIs
How do you know if refactoring went successfully? Below we list several KPIs that indicate the high quality of code and can serve as goals to achieve during the code refactoring process:
- Code can be easily understood by any developer on the team;
- New features can be implemented easily and/or quickly after refactoring;
- Code is concise and its length is finite;
- A limited number of classes that duplicate each other’s logic.
While seemingly simple, these goals can be quite hard to achieve especially if you do not perform refactoring regularly and your technical debt keeps growing. Hence, we highly recommend making refactoring a habit and trying to balance both the quality and tight deadlines. Another good practice is updating your documentation after refactoring since you’ll be gaining new experience and will be aware of the most efficient solutions to use in the future.
Comments