Refactoring is not so scary
Tags: refactoring, cleancode, languageagnostic
Published: 2017-08-19 09:56:52

---
title: Refactoring is not so scary
published: true
description: A few ideas to make you feel less intimidated about refactoring your spaghetti code
tags: refactoring, clean code, language agnostic
---

### What is refactoring?
The answer to this question is very crucial for your understanding of the whole process. *Refactoring* is making changes in the *structure of code*, while not making changes to the *functionality*.
By the way did I say **process**? Yes I did, because it is a continous process and we often forget about that. Lately I've asked a fellow programmer in my company *"So how do you integrate your development process with refactoring?"*. He said *"Everytime after the sprint we are given some time to refactor"*. So why is this a bad practice? Because after a whole sprint you don't have as much context as you did when you've been coding every functionality. You have to: read the code, understand the code, switch to the other functionality, repeat. Think about how efficient it would be when you do this **while** you're coding this new fresh stuff.
So once again, *refactoring* is a process that you should apply in parallel to writing code!

### Why do we want to refactor?
The answer is simple - **refactoring saves costs in the future**.
Every project which is getting bigger is also getting more complex. If the code quality doesn't go along with the complexity, everyone will spend a lot more time reading it. Even for the new, greenfield projects the ratio of writing/reading code might be something like 30%/70% (and it goes up to something like 5%/95% in bigger projects). If you think about optimization of these 70% and multiply it by the amount of team members, it could lead to huge savings. Now, don't you think that making your code more readable would help a lot in the future?

### How do I refactor?
Let's say you're implementing a new feature and you just wrote that fresh new class that handles some operations. As the class is getting bigger you're going to see more flaws. How can you spot them? Clean code to the rescue!

- **Functions length** should be approximately 7-20 lines of code. No more. In some specific situations you won't be able to achieve this, but as you spot some lines of code that could be given a name, just extract them to a new function (you don't have to count *if*, *while* etc. as whole line, just their bodies).

- **Function arguments** should be *approximately* taking 3 arguments. Ideally you'll want to take *zero* arguments and all data would be taken from class' properties. It's not always possible so at least try to not make them more than 3.

- **Class length** should be approximately 150 lines of code. Why? Because most probably it breaks SOLID's [Single Responsibility Principle](https://en.wikipedia.org/wiki/Single_responsibility_principle) - a class should do only *one* thing and should do it well.

- **Indentation** should be approximately 2 levels deep. Let's show you an example just for clarity:
```Java
public void doSomething() {
    while(conditionIsMet()) {
        if (anotherConditionIsMet()) {
            doSomeLogic();
        }
    }
}
```
Don't go beyond that and you're good to go. When you are about to go deeper - **extract** to functions!

- If you have to use the word *and* in your function name, then there is something wrong with it. Once again [Single Responsibility Principle](https://en.wikipedia.org/wiki/Single_responsibility_principle) of SOLID.

- **Extract to variables and functions** everytime you can provide a clear information about its purpose. Especially extract the bodies of loops to functions and number/string literals to constants!

Before:
```Java
  product.grossValue = product.price * 1.23;
```
After:
```Java
product.grossValue = calculateGrossValue(product.price);

public double calculateGrossValue(int productPrice) {
  return productPrice * PRODUCT_FEE;
}
```

- **Simplify conditions by extracting them**. Similar to previous one but now we are targeting conditions in *if*, *while*, *for* statements etc.

It's easy to see what is the condition for the *if* statement in this particular scenario
```Java
if (!inventory.cars.isEmpty()) {
  doSomething();
}
```

But wouldn't it be more readable like this?
```Java
if (carsInInventoryNotEmpty()) {
  doSomething();
}

private boolean carsInInventoryNotEmpty() {
  return !inventory.cars.isEmpty();
}
```

- **Never** allow duplication of code! If a bug ever happens in one place, you will have to cover every other and most probably you will miss one of them. Instead look for a smart abstraction that you can extract. [Design patterns](https://sourcemaking.com/design_patterns) are very helpful in getting out of sticky situation.

- **Don't use comments**. Instead try to name your functions and variables better. Comments are allowed only for **TODO**, **FIXME** (not on master branch though) and some special cases where you would want to describe your intentions instead of mechanism.

These are my rules of thumb to keep my code clean and organized. You can [read more](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1) about other rules in the Uncle Bob's book or in many other resources on the internet.
It's also good to take a look at [catalog of refactorings](https://refactoring.com/catalog/) and see more tools to make your code better. Also most basic refactorings should be available in your IDE. Use it whenever you can, because your IDE is smart and will not let you refactor if it will break anything!

### Summary

The idea of refactoring is not to make everything perfect at once. Instead you want to make a lot of small changes that have any positive influence on your code. Every time you make a change, ask yourself: *will it be more readable to me and other people that might come across this?* If the answer is *yes*, then you should keep it.
Remember, you produce code for humans after all, not machines. And yes, you can make a difference :) Good luck!

What are your thoughts on this topic? Share your best practices in the comments!