This article is based on a reading of “Refactoring”, the Ruby Edition by Jay Fields, Shane Harvie and Martin Fowler.
My intention is to refresh some basic concepts about Refactoring, because even though it is a very popular subject, there are still a lot of different ideas that the authors of the book are trying to explain.
The idea of refactoring is to provide a variety of solutions for different cases when changing parts of your code. Let’s take a look at the definition:
A change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
To restructure software by applying a series of refactorings without changing its observable behavior.
The most important points here are that these changes should not change the behaviour of that code, and it should be made with “small changes“.
Importantly, this is one of the key concepts that is often different from most people’s understanding.
Managers used to think that refactoring means change a lot of things: renew the ‘old code’ with ‘new code’. This promotes the notion that refactoring is a big project, that generates large costs, and therefore needs to be addressed in a more controlled way, booking in time, or just simply postponing any change. But why would we change something that already works?
So, when we should refactor? Leaving apart the case that big changes could happen, the idea of refactoring is to create a habit of making small changes to the code in order to make it readable, cleaner and much more simple than it was before.
Getting into this habit is something that takes time, and it’s not very easy. Identifying what needs to change and the challenges, is the purpose of refactoring, providing techniques and helping us to identify when the code needs to be changed.
Applying refactoring will help us to get these benefits:
Changing the code, without changing the behaviour makes us ‘test’ it; we could end up finding bugs and corner cases.
You might think at this point, so we should ask: is refactoring just cleaning the code up? Yes, it is, but as Martin Fowler mentions in the book, “it goes further because it provides a technique for cleaning up the code in a more efficient manner”.
In order to apply the proper techniques we first need to identify what these cases are where the code is asking for a refactoring? The code smells. We normally talk about clean code, but also we need to talk about dirty code, and this one smells.
Code smells: “A code smell is a surface indication that usually corresponds to a deeper problem in the system. The term was first coined by Kent Beck while helping me with my Refactoring book.” Martin Fowler
These are cases that indicates that there is trouble and they can be solved by a refactoring:
We are not going to explain each of them here. There is tons of documentation about it. But the interesting thing here is that we have probably been working in a lot of those code smell situations, but without knowing that they have names and can be properly identified. And better, that someone has already systemised a method of solving them.
The way the code smells are grouped in that image come from Refactoring Guru, a great website by Alexander Shvets where we can find a really good and fun explanation about refactoring, design patterns, etc...
We can easily identify the different code smells by those groups:
Take a look at that image again. We can identify the typical cases that we are used to find.
We normally make the same mistakes, so we are used to find typical code smells.
These are my list of common code smells:
There are many more common situations, but I removed the “Object orientation abuses”, because I think the others are easily to find. In fact, code smells come from the detection of common situations after analysing a lot of code.
Those are probably my most easy to find code smells situations.
Which are the techniques that refactoring is talking about?
This is a list of the techniques we can use for solving code smells. Sometimes we can use several of them.
To give us an idea of how to apply them to the different cases, this is a relation of the common techniques used to the common smells we mentioned before:
We are not going to go deep in code examples. The idea of this article is to refresh the principles of refactoring, see the concepts, and show refactoring in an easy way to encourage the readers to explore them and play with them.
There are a lot of tools to help us identify code smells in our code. I will point to one that I discovered recently and I am still exploring: Reek.
Install the gem, run it, and take a look at how your code smells.