Intive Blog

Refactoring (and code smells)

A good way to start this article is to define Refactoring: it is the process of taking an existing code and changing it so that it becomes easier to read. The key is that when a code is modified, its functionality should not be affected. It is not complex to write code that a computer can understand, but it is not easy to make a human being understand it. To identify where a refactor should be made, we can be guided by code smells, which are typified on the article “A review on the most common code smells”.

Code smells –or code stench- are superficial indicators of some kind of issue in the system. They are called smells since they are volatile. There are no metrics capable of spotting them. They are structures that can be seen in the code and suggest the possibility of a refactor. As a programmer, consequently, the challenge is to develop your own intuition to know when there are too many code lines, variables, etc.
We will explain this step by step…

What is Refactoring for?

We highlight among the features of the process:

  • It improves the design of the code previously written
  • It is a disciplined way to clean the code to eliminate chances of introducing bugs
  • It makes software easy to understand
  • It keeps a high speed of software development

Even when understanding its features, many questions may come up: How often should I refactor? Every two weeks?, Or only when I do see that the code is actually awful?

No! Because of the following:

  1. Performing refactoring is not something you should allocate time to as a task. We do it all the time as small bursts. We do not decide to refactor, we do it because we intend to do something else, like adding a feature, and the refactoring allows us to do so more effectively.
  2. You need a purpose that adds value to the application. If the code works, you should not refactor. In fact, it is recommendable to avoid the infinite loop of refactoring.

So, when is it correct to perform Refactoring?

  1. When adding a feature.
  2. When correcting a bug.
  3. When performing code review.

 

Watch out! Some warnings for the refactoring time

To carry out this process it is important to have automatic tests to know whether we have introduced a new bug when refactoring, which is very commonplace. Reliable testing will assure us to make the necessary change for the software. However, programmers reject the idea that a code refactor works when not available, and they could not be more right.

Many refactors imply finding all the references to a variable method or class. When you do this, it is recommendable to resort to an IDE (Integrated Development Environment) that is being used to find them and reduce the chances of losing reference.

 

Some common refactors:

  • Method Composition: A great part of refactoring is the composition of methods to pack the code appropriately. Normally, problems come up when methods are very long. They are problematic because they generally have too much information, which gets buried by the complex logic they present. Key refactors are extract method and inline method:
Extract Method Converts a fragment of code into a descriptive name of its purpose. It improves legibility and helps reduce code duplication.
Inline Method Replaces the calls to a method with copies of the method body, since this is as descriptive as the call.
  • Moving behaviors among objects: The main decision of object design is where to assign responsibilities. You will probably have to refactor in a near future to keep the design up to date with custom software to which features are added. Bellow you will find a list of the most common:
Move method & Move Field Moves a method or attribute to the class which uses it more often. Assign responsibilities correctly
Extract Class & Inline Class Counterparts for classes of extract and inline methods. Create or merge classes to separate or put responsibilities together.
Remove Middle Man Removes intermediate classes that only take messages from one class to another and do not have actual responsibilities.
  • Extract class:

unodos

  • Remove middle man:

trescuatro

  • Organizing data: These techniques help data management, replacing primitives with useful features or the class. Another important result is that they untangle associations among classes and increase encapsulation to make them more portable and reusable:
Self-encapsulate field Uses accesors to encapsulate class behavior
Replace data value with object Creates an object for a data group and their related behavior, it then creates a reference to the object in the class from which data were extracted
  • Accesors (self encapsulate field):
  •  Simplifying conditional expressions: Conditional expressions become increasingly complex along time. Here are some solutions:
Break down conditional Some conditionals are complex. To deal with them we must create sub-methods for them
Introduce null object We have null check-up’s, Consequently, we can create a null object as subclass with default behavior.
  •  Simplifying method calls: These techniques make calls to methods easier to understand. They simplify interaction among classes. Let’s see:
Rename method Increases the code expressivity to make it easier to read.
Keep entire object Passing an object with many variables as a parameter instead of passing it by separate.
  • Dealing with generalization: Abstraction has its own group of techniques called refactoring. These are mainly associated to moving functionality along the hierarchy of heritage of the classes, creating new classes and interfaces and replacing heritage with delegation and vice versa:
Move up field Utilize polymorphism with subclasses containing the same behavior or data
Replacing delegation with heritage A class has too many simple methods that delegate methods of another class, so we have to adapt it as a subclass to inherit this behavior
  • Replace delegation with heritage:

cinco6

After this comprehensive review, we want to share some links you might find interesting:

  • Here we can find symptoms, causes, fixes and rewards for every type of code smell.
  • Here, more about refactoring.
  • And here yuoan read the book “Refactoring to patterns”.

Santiago Pugliese

He is a developer in intive – FDV since February 2016 and leads the Backend Team. He also works wit Node.js. He studies the Systems Engineering degree at the National Technological University (NTU). He is a Technical Electronic and Electromechanical. He stands out for its creativity and when he is not working, he plays harmonica, piano or draws.

Add comment