Refactoring, does it help?

Refactoring, is the general idea, helps to get a higher degree of understandibility and changeability of your code. Refactoring, in short, enhances the quality of code.

That is the hunch we all have. But in practice, it is hard to prove. Recent research, for instance, show that refactoring does not lower code complexity, which is counterintuitive1,2.

You could almost speak of a war: in this article, the authors state that refactoring did not improve code quality. Developers answered, of course. The problem, I think, is partly that `code quality’ is inherently hard to measure (and cannot be measured directly), and that – maybe – refactoring serves a slightly different purpose than anhancing understandability and changeability, and minimizing complexity. Here is my view.

Refactoring: untangling knots?
Refactoring: untangling knots?

Measure code quality

In the first place, there is no agreed method to measure code quality. When programmers refactor code, they – obviously – value the quality of the refactored code higher than the quality of the code before the refactoring. To objectify such a valuation, you might have the code before and after valuated by experts over the world, with no ties to the programmers who did the refactoring. In the article mentioned above, students were used as `experts’, which might explain the outcome.

Understandability of refactored code

When you have to study code that you did not write yourself, you will, probably, tend to rate the quality of code that you can understand easily higher than that of code that is harder to understand. But is there really always a positive correlation between understandability and code quality? I think not.

Abstraction and understandability

Abstraction is one of the design principles of the Software engineering body of knowledge. Undeniably, abstraction helps to enhance changeability of code, and to minimize duplication. On the other hand, abstract code is sometimes harder to understand.

As an example, take this simple JavaScript function to check whether a number is even:

function isEven(number) {
 return number % 2 == 0;
}

Suppose that it is probable that, in the future, one might have to check whether a number also can be divided by three or five as well. To anticipate such changes, the code might be refactored to:

function divisibleBy(number, divisor) {
 return number % divisor == 0;
}
function isEven(number) {
 return divisibleBy(number, 2);
}

The code is more abstract, and the changeability is enhanced, but the code is not necessarily easier to understand.

Decoupling and complexity

The degree of decoupling is a measurement of code quality. But decoupling code may enhance the complexity. An example is when the strategy pattern is applied on a class that should have multiple algorithms to sort:

The Strategy pattern applied
The Strategy pattern applied

The advantages are that any object that asks TaskList to sort itself, does not need to know which method to use, and the same applies to TaskList itself: the knowledge which sortmethod to use is decoupled from TaskList and its clients.

But it is obvious that the resulting code has more classes than when TaskList would just offer three sort-methods.: the resulting code is more complex. Complex code is harder to understand.

So what is the goal?

Summarizing, when refactoring code, there are many trade-offs between different aspects of code quality. Therefore, one cannot just say that the goal of refactoring to enhance code quality. Also, it is difficult to rate code quality because understandability plays such a big role.

In my opinion, refactoring should make code more robust with respect to changes. That might even not imply that it will be easier to apply changes in the refactored code. Refactored code, I think, anticipates on future complexity.

Anticipate future complexity

The problem with applying changes to software is that, very easily, the software becomes so complex that it will be almost impossible to apply more changes without the certainty that bugs will be introduced (David Parnas calls this `Software aging’).

Refactoring should anticipate such a future complexity: refactoring builds in measures to handle future complexity.

Unfortunately, that benefit of refactoring is even harder to measure than code quality…

Footnotes
  1. Studying the effect of refactorings: a complexity metrics perspective, Quinten David Soetens and Serge Demeyer, Proceedings of the 2010 Seventh International Conference on the Quality of Information and Communications Technology (QUATIC).
  2. Does the act of refactoring really make code simpler? a preliminary study, Francisco Zigmund Sokol, Mauricio Finavaro Aniche,  and Marco Aurélio Gerosa, 4th Brazilian Workshop on Agile Methods, 2013.

One thought on “Refactoring, does it help?

Leave a Reply

Your email address will not be published. Required fields are marked *