Refactoring — an ode to code
Tags: refactorit
Published: 2020-06-24 13:51:53

What is refactoring? Should you redo your whole project? How can you proceed?

This article will give you an **overall** explanation of **refactoring** in software development.
We will **explore** the theory and then **present** some examples from real life.
But, as I always say, no explanation is complete without clarifying the benefits and challenges first.

Let's get to it, shall we?

## What is it?

![](https://dev-to-uploads.s3.amazonaws.com/i/1y1go7psnllgme531ftx.gif)

Refactoring refers to independent techniques and steps to improve code that has already been written.

To make it short, refactoring is the **art of increasing the maintainability of a piece of code**.

> There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies. <br/> —  C.A.R. Hoare

But don't get me wrong, having to refactor your own codebase is not bad. It doesn't make you a poor-skilled developer.
Actually, during your career you will always be refactoring code (yours or others).

The **Technical debt is a complete part of the development process**, as nicely stated [in this article from Marc Friederich & Gilles Doge](https://antistatique.net/fr/nous/bloggons/2015/05/22/la-dette-technique).

> On a standard 101-key keyboard, there are 100 keys that increase technical debt, and only one key that reduces it. <br/> — Josh Wulf

During a refactoring process, you might be doing a lot of changes, adding new Classes, renaming, reorganising. But remember, **at the end of your journey you won't ever be altering the observable behaviour of the code**.

First, refactoring is **not debugging**. Your code needs to be running in the first place.
Of course, during a refactoring process you may find bugs. The moment that you start dealing with them, you've stopped refactoring and started bug fixing, which is another mindset.

Second, refactoring is **not about performance**. 

I was speaking with a young developer the other day who was trying to convince me that refactoring a codebase makes it obviously faster. 

It is a very common misconception that bad code automatically leads to performance leaks. The performance of your code is not the goal of a refactoring process - nor even what you should expect out of it.

Finally, refactoring is **not adding features**. 

When you are refactoring a part of your code, you should not change its behaviour, otherwise you are no longer refactoring.

## Should you do it?

People who have been using your app will have no idea something changed behind the scenes.

You did not fix bugs, you did not make it faster, you did not add any new feature.

So, you may ask me "why should I refactor then?".

> If an application that was written for a long time and remained then untouched is working as expected, if there's no conflict with any other system, if no features need to be added in the future,
then it can be the ugliest code in the world: it doesn't need to be refactored.


Well, the answer is quite simple. **Well-structured code will make it so much easier to add new features and new capabilities in the future**. And, it will make it easier to start analysing performance or overall improving the application. 

By improving the code quality, you will also improve the overall team efficiency, certainly save a fair amount of money and make your developers happy to work on that codebase - or at least I hope so.

> It's called technical debt, because it's like taking out a loan. You can accomplish more today than you normally could, but you end up paying a higher cost later.

If you face tedious difficulty getting approval on spending time for refactoring - because the benefits aren't immediately apparent - remember that **you're not refactoring for your end-user, you're refactoring to get the future roadblocks out of your way**.

## How do we do it ?

> For non-developer people, this part may be more tricky. <br>Fly, you fools !

Bored of reading theory? Alright - me too - let's dig into some real-life examples.

![](https://dev-to-uploads.s3.amazonaws.com/i/57f035l07dxnccca40ok.gif)

> Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. <br/> — Martin Golding

There is no such thing as a set of rules or a specific order that anyone can just follow, but there is a set of techniques to help you refactor code. Here I will drop some of my favourites and easy ones to try to use in every project.

One more thing, if I could give you one piece of advice, and share insight on one thing it would be this one simple sentence: "**Never refactor a production code that does not have unit tests**". 

The main reason is maybe pretty obvious, but let me say it out loud again:  without unit tests, you will end up with broken functionalities that are nearly impossible to fix because you won't be able to figure out what's happening anymore.

So please, if you have to refactor something, first make sure it is covered by tests.

![Where are the tests?](https://dev-to-uploads.s3.amazonaws.com/i/tkqtj33ud55b1vmvsv9x.jpg)

####Conditional Guard Clauses (return early)

To keep readability in functions and methods, it's wise to return early if simple conditions apply that can be checked at the beginning of a method. Then, when it's hard to determine the normal flow of code execution, try to isolate checks.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ConditionalGuardClauses-bad.php %}

It's **better to return early, keeping indentation and brain power needed to follow the code low**.

Isolate all special checks and edge cases into separate clauses and place them before the main checks. Ideally, you should have a flat list of conditionals, one after the other.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ConditionalGuardClauses-good.php %}

####Assignments to Parameters

Sometimes, you will need to alter a given parameter value inside your own method body.
If this parameter is passed via reference, then after the parameter value is changed inside the method, this value is passed to the argument that called this method.
Very often, this occurs accidentally and leads to unfortunate effects. Even if parameters are usually passed by value (and not by reference), this coding quirk may be weird to those who are unaccustomed to it.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ConAssignmentsParameters-bad.php %}

Use a local variable instead of altering the parameter.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=AssignmentsParameters-good.php %}

####Replace Array with Object

`Arrays` are an excellent tool for storing data and collections of a single type.
But if you use an array like post office boxes, storing the username in box 1 and the user's address in box 14, you will someday be very unhappy that you did that way.

You have an array that contains various types of data.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ReplaceArrayWithObject-bad.php %}

Replace the array with an object that will have separate keys for each element.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ReplaceArrayWithObject-good.php %}
    
Plus, using `Object` over `Array`, you will be able to apply properties assertions, I would suggest everybody to take a look at the [`ArrayAccess` implementations](https://www.php.net/manual/en/class.arrayaccess.php) which is great to replace object-like `Array`.

####Replace Magic Number with Symbolic Constant

Magic numbers or magic values are encountered in the source code but have no obvious meaning.
This "anti-pattern" makes it harder to understand the program and thus refactor the code.

Often, a simple Find & Replace won't work on those values, as the same data may be used for different purposes in different places, meaning that you will have to verify each line that uses this value.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ReplaceMagicNumber-bad.php %}

Replace this number with a constant that has a human-readable name explaining the meaning of the number.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ReplaceMagicNumber-good.php %}

####Consolidate Conditional Expression

When your code contains a lot of alternating operators that perform identical actions, it is not clear why the operators are split up.

The main purpose of consolidation is to extract the conditionals to separate methods for more clarity.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ConsolidateConditionalExpression-bad.php %}

Consolidate all these conditionals in a single expression.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=ConsolidateConditionalExpression-good.php %}

####Use the language capabilities

Often, developers forget some awesome capabilities of the programming language they use.
Many of these features can save you a lot of effort. Take a look at the next examples and notice how it can be easy to achieve the same result by using the type `hinting` methodology.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=LanguageCapabilities-bad.php %}

Could be changed to a simpler method with the same capabilities

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=LanguageCapabilities-good.php %}

####Inline Temp

Prevent usage of temporary variable when necessary. For example, when you have a temporary variable that is assigned the result of a simple expression and nothing more.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=InlineTemp-bad.php %}
    
Replace the references to the variable with the expression itself.

{% gist https://gist.github.com/WengerK/fedb5c09240cc5b944bb520a5ff5a71e file=InlineTemp-good.php %}

####What else ?

I would like to end with a few more quick tips on better coding:

- Use a new array form `[ ]` instead of the old `array()`
- Use `===` operator instead of `==` unless it is important to not check for the `dataType`
- Use prefix `is/has` with functions that return boolean ex: `isAdmin($user)`, `hasPermission($permission, $user)`
- Organise class methods with public methods at the top
- Always apply the single responsibility concept to your classes

![](https://dev-to-uploads.s3.amazonaws.com/i/m0kh8jgu7tis1qjowmwy.gif)

<hr>
## Sources

For the most curious of you, here are some sources of additional information that inspired the creation of this article.

Sourcemaking (23 August, 2019). Refactoring 
See on [https://sourcemaking.com/refactoring](https://sourcemaking.com/refactoring)

Refactoring Guru (23 August, 2019). Refactoring Guru 
See on [https://refactoring.guru/refactoring](https://refactoring.guru/refactoring)

Mohamed Aladdin (19 August, 2018). Refactor Your PHP legacy Code (real projects examples) 
See on [https://medium.com/hackernoon/refactor-your-php...](https://medium.com/hackernoon/refactor-your-php-legacy-code-real-projects-examples-da9edf03ff4b)
 
Josh Wulf (15 April, 2018). There is no good coding, only good refactoring 
See on [https://medium.com/@sitapati/there-is-no-good-...](https://medium.com/@sitapati/there-is-no-good-coding-only-good-refactoring-487f322b5987)

Fionna Chan (11 October, 2018). Code Refactoring — How to Write Better Code 
See on [https://medium.com/@fionnachan/code-ref...](https://medium.com/@fionnachan/code-refactoring-how-to-write-better-code-d1aeab549597)

Thomas Deniffel (20 April, 2019). Brutal Refactoring)
See on [https://medium.com/@tdeniffel/brutal-refactorin...](https://medium.com/@tdeniffel/brutal-refactoring-31b5cc4d4512)

Samuel Roze (21 August, 2018). Refactoring the right way: regional, not global
See on [https://medium.com/@sroze/refactoring-the...](https://medium.com/@sroze/refactoring-the-right-way-regional-not-global-692643b1947e)

Omar El Gabry (02 October, 2017). Refactoring — The Hygienic Habit
See on [https://hackernoon.com/refactori...](https://hackernoon.com/refactoring-the-hygienic-habit-b2ee0f5528ba)

Shawn McGrath (22 August, 2016). The Exceptional Beauty of Doom 3's Source Code
See on [https://kotaku.com/the-except...](https://kotaku.com/the-exceptional-beauty-of-doom-3s-source-code-5975610)

<small> _The copyright for CommitStrip is held by [CommitStrip](http://www.commitstrip.com) and is licensed to CommitStrip._ </small>