Refactoring a real-case
Tags: javascript, refactoring, cleancode, designpattern
Published: 2019-02-22 23:17:24

---
title: Refactoring a real-case
published: true
description:  I will show different refactoring steps that I have applied in a real-case to improve the quality of the code.
tags: javascript, refactoring, clean code, design pattern
---

*****

*Originally published at [www.carloscaballero.io](https://www.carloscaballero.io/refactoring-a-real-case/) on December 28, 2018.*

*****

As a result of publishing the series of post of the [clock-in/out
system](https://carloscaballero.io/clock-in-out-system/), I had the need to
write a function to import the data from a large XLS file to a Postgres database
using the ORM (TypeORM).

This function was written quickly as a script without thinking too much about
the quality of the code, but simply “work”. However, once the system is working
and a test suite is available, it is a good idea to go through a constant
refactoring to improve the code.

Next I will show different refactoring steps that I have applied to this
function to improve the quality of the code. Therefore, the function that we are
going to improve is shown first.

![](https://cdn-images-1.medium.com/max/1000/1*0HhII86DZiJuAzYY89R9nA.png)

* **normalizedUID**: this function is used to generate the name/uid (string) of
each teacher.
* **getDaysByTeacher**: Returns an array in which each position represents each
user’s day. Each of the days is also represented by an array. Hence, this
function returns an array of arrays in which we will have organized the weekly
working hours of each user (fixed schedules).
* **factorySchedule**: Create a schedule object from another object composed of
the room, hour and number of day.

![](https://cdn-images-1.medium.com/max/1000/1*OCkqygyRWkOkWJ_MZdVuDA.png)
<span class="figcaption_hack">import.ts</span>

The main code would be as follows after the extraction of functions:

![](https://cdn-images-1.medium.com/max/1000/1*6HlohEq2Vc6kJF5oZLIB8g.png)

Before going on to address the next phase of refactoring, we will eliminate the
variables that are understood using the domain of the problem, also the
temporary variables will be removed.

![](https://cdn-images-1.medium.com/max/1000/1*F6BiwJoXb70BWrH1JSGzwg.png)

In this moment, we see that we are making use of one of the most powerful
features of **JavaScript, functions as a parameter** in the **forEach** methods.
But really, the **forEach** methods are only acting as syntactic sugar against
the classical **for** of the imperative programming. Therefore, we will be
modifying each **forEach** method by the most appropriate one according to the
task that they perform.

The first **forEach** loop that we are going to address is the following:

![](https://cdn-images-1.medium.com/max/1000/1*ud0fKT3iNVcO8qcADMZSzw.png)

This loop can be transformed into the method **reduce** because of what we want
to get a single value (**an array**) after iterating through each of the days.
In addition, the **schedule** variable can be omitted and the
**factorySchedule** method can be invoked directly since the creation of this
variable does not add semantic value in the code.

![](https://cdn-images-1.medium.com/max/1000/1*CV2RwATNgzPJ1RrCzMEvHQ.png)

If we observe the function performed in the body of the method **reduce,** it is
an if-else which can be transformed into a ternary operation that we can combine
with the potential of immutability (another characteristic of functional
programming) leaving the code as follows:

![](https://cdn-images-1.medium.com/max/1000/1*IPhlkpB_1l5dqtljqQfACQ.png)

Another small step in the refactoring would be to omit the explicit invocation
of return when using fat-arrow (lambda functions) of JavaScript, leaving the
code as follows:

![](https://cdn-images-1.medium.com/max/1000/1*Ha-yyz_dcAxU8Y87pGqXLg.png)

If we look at the code, the next natural step will be to replace the **forEach**
method that includes the **reduce** by another method **reduce**. It may seem
complicated the code that will generate since we are using the features of
fat-arrow and spread operator (…) which if you never are used before can seem
abstract (we will solve it by creating functions that allow you to decompose the
task).

![](https://cdn-images-1.medium.com/max/1000/1*FQiTCy4yAv3XV5U_q31PZQ.png)

Therefore, the next step is to build small functions that perform the task that
is done within each of the **reduce**. But we have a small problem, we need to
pass extra parameters to each of the callbacks of the reduce methods. This
problem is easily solved in JavaScript with different techniques such as
overwriting the scope (this), using variables from a larger scope, or your own
such as the **bind**, **apply** or **call** methods.

In our case, we are going to create several small functions that combined with
the bind method will solve the problem of passing parameters in the callbacks.
In this way, the resulting code until this moment would be the following:

![](https://cdn-images-1.medium.com/max/1000/1*H4bqWhBeAcSAA3prCDWH5w.png)

The next step is to address the **forEach** method that encompasses the entire
main method. The elimination of this method will allow us to eliminate the two
variables that act as accumulators (**users** and **schedulers**). In such a
way, that the method reduce will receive as an accumulator an array that
contains two arrays (**schedulers** and **users**), which will be unstructured
to be able to be concatenated easily in the method reduced.

After refactoring the code we find the following version:

![](https://cdn-images-1.medium.com/max/1000/1*OWPC3Ddr96u94EejCCK33w.png)

In the same way as we did in the previous case, the method **reduce** receives a
callback that is the one that performs the conversion to JSON, and finally we
rename the content of the file to a variable called xls. So the partial result
is the following:

![](https://cdn-images-1.medium.com/max/1000/1*SLCL-CRNY_ZXlwX4__XhBg.png)

Finally the result of the script after making these changes is shown below:

![](https://cdn-images-1.medium.com/max/1000/1*zK0E804pPOItRWIt0K14Xw.png)

Summary

1.  Extract functions.
1.  Name the functions and variables must be an identification value.
1.  Use the built-in language methods for your use (**forEach** against of
**reduce**).
1.  Abstract complexity and details of the code to auxiliary functions of lower
level.

*****

*Originally published at [www.carloscaballero.io](https://www.carloscaballero.io/refactoring-a-real-case/) on December 28, 2018.*

*****


Hi! My name is Carlos Caballero and I’m PhD. in Computer Science from Málaga,
Spain. Teaching developers and degree/master computer science how to be experts!