Refactoring: What is It, and When is It Best to Perform It?

Maintaining the existing code is a very important process that shouldn't be downplayed. Unfortunately, more time and resources are often spent on implementing new functionalities at the expense of maintaining the current code. Of course, we all may sometimes be asking ourselves: why fix something that already works? What benefits may it bring?

What is refactoring?

According to Wikipedia, it's a process of introducing changes to a project or program, as a result of which the functionality doesn't substantially change. Therefore, refactoring aims not to create new functionality but to maintain the system's appropriate, high-quality organization.

Now let's try to translate this definition so that everyone may understand it. For this purpose, I'll use the following sentence as an example: The driver of a motor vehicle which, while moving on the road, is being overtaken by another motor vehicle, should stop speeding up until the end of the overtaking maneuver.

The sentence is long and complicated, but we're able to understand its message after a while. On the other hand, the sentence We shouldn't be speeding up if we are being overtaken by another vehicle is much shorter, easier to understand, but at the same time still provides us with important information.

Therefore, we may convey the same information in many different ways, some of which will be better while others will be worse. The same goes for programming. The operation of a given functionality may be written in the form of a code in a better or worse way, but the result will remain unchanged. And here we come back to code refactoring, which is nothing more than changing code content without affecting the final result. Then why change something that works, and what effects does it bring?

When should we perform refactoring?

Before we explain why we should change something that is functional and the results such a change brings, let's first take a look at the symptoms that an application requiring refactoring may give.

Lack of support or the imminent end of support for the CMS the application is based on

The end date of support for the CMS or the framework on which the application is based is nothing more than its use-by date. After this date, the application should no longer be used. This is very important – not so much in terms of the application's performance, but rather its security. Let's take a look at the table below, with the deadlines for ending support for the Laravel framework.

A table with the end of support dates for different versions of the Laravel framework

Source: Laravel.com

The most interesting thing in this table is the Security Fixes Until column. Its title means that no security patches will be implemented after the specified date is exceeded, even if a vulnerability is discovered and reported. This is the perfect opportunity for an attacker because if they are dealing with an already unsupported system, they'll know exactly where and what kind of vulnerabilities are there, which will make the attack much easier.

How much time and work you'll have to spend on updating the application depends on many factors. For example, migrating from Drupal 7 to Drupal 8 actually means a complete rewrite of the application. The same goes in the case of some versions of Laravel.

Slow operation of an application

This is a very common phenomenon that may take several years to develop any symptoms. Why does it happen? The initial goals of the design stage of the application may not take into account the performance of the application in the case of increased traffic on the website or in the case of working with larger amounts of data. This data stores information, e.g., about the registered users, posts, comments, application settings, etc. Over time, there'll be more and more of them, and they'll cause more and more problems.

However, you should keep in mind that the slow operation of an application doesn't always mean the need for refactoring. Sometimes, to speed up its operation, e.g., changes in its infrastructure will be necessary. For this reason, the decision to refactor the code should be preceded by a thorough analysis.

Long development time

A well-written application should allow relatively easy implementation of new functionalities and changes. For this to be possible, every developer should follow certain rules when writing code, such as DRY or SOLID. Unfortunately, this is a far cry from reality, and programers often have to develop code that was originally created by people unfamiliar with these rules. Due to this, adding the simplest functionality sometimes takes an absurdly long time.

In such a situation, you also need to thoroughly analyze the code and consider whether total refactoring will be more profitable than developing the current code. If you decide to refactor, it should be treated as an investment. Your time and resources won’t give you immediate results, but they'll allow for saving resources in the future.

Common mistakes that often need to be fixed

This aspect is somewhat related to the previous one. Of course, mistakes happen to every person, and sometimes, despite the best intentions, many tests, and the QA team, they may occur anyway. However, if they are becoming more often, or the majority of programers' working time is spent on fixing bugs rather than on optimizing and developing the application, it may mean there's a need to refactor.

How does the refactoring process look like?

As we've already mentioned, the decision to refactor should be preceded by a thorough analysis. How does it look like then, what does it consist of, and what are the stages of the process of refactoring the code?

  1. Getting to know the application, functionalities, and business logic. At the beginning, we need to learn about the exact operation of the application processes, as well as what task it performs.
  2. Checking the used technologies, frameworks, or CMSs in terms of updates and the support period. Internet applications very often consist of numerous components, modules, and packages provided by third parties. You should check if they are still supported or if they need to be updated.
  3. Analyzing the code in terms of its quality, best practices, and performance. At this stage, we assess whether the current code is usable and whether its further development won't be problematic.
  4. Identifying the causes that have a negative impact on the operation of the application. On the basis of the previously collected information, we analyze the processes taking place in the application and identify the weakest links that affect performance.
  5. Identifying the solutions that will improve the operation of the application and determining the method of their implementation. Knowing the problems, the application is suffering from, we look for the solutions that will work in a given case. Every problem may be solved in many ways, so we carefully weigh all the pros and cons.
  6. Estimating the costs, working time, and tasks to be performed. We write down the action plan in the smallest details, divide the tasks into stages, and estimate the amount of work needed to complete them.
  7. Preparing automatic tests. Thanks to them, during every stage of work, we'll rest assured that the application will run in a stable manner throughout the entire process and that there will be no unforeseen failures or other problems.
  8. Code refactor – implementing the previously planned changes.

It's impossible to clearly define how the code refactoring itself will proceed. It's a very complex issue and, depending on the situation, the whole process will be different. However, the most important thing is not to interfere with the application's operation during the entire refactoring process, so that the users don't experience any problems.

Treat refactoring as an investment

Sometimes it's very difficult to explain the point of refactoring. It's also not easy to convince someone to spend money, sometimes not a small amount, on a process that won’t introduce any changes to the application that are visible to the naked eye. However, keep in mind that refactoring should be treated as an investment. The money spent now won't bring an immediate return, but it will allow us to save resources in the future. In addition, our application will be more stable, more resistant to attacks, and the implementation of new functionalities or other changes will be much faster.

Do you have an application or website based on PHP or one of its frameworks (Drupal, Laravel, or Symfony)? As PHP development specialists, we can analyze its code and – if necessary – perform the refactoring.

3. Best practices for software development teams