Spring Cleaning — Time to clean up your code

Quentin Ferrer
7 min readMay 11, 2020
Background image by Francesco Mazzoli

Spring has arrived! At this time of year, everyone cleans their house thoroughly. As a developer, I suggest a different approach: Clean up your code.

What is clean code?

Clean code is easy to read, understand and maintain by the author of the code and other developers.

Why you should write clean code?

Writing clean code is a necessary mindset. It is very important for you and your co-workers. It will be easier and faster to improve, maintain and test a product if everyone understands the code. This increases the quality of a product and decreases the technical debt.

️How to clean your code?

The refactoring is to fight technical debt. It transforms a dirty code into clean code. Refactoring should be done as a series of small changes, each of which makes the existing code slightly better while still leaving the program in working order.

Step 1: Rename method

Problem

The name of a method doesn’t explain what the method does.

Solution

Rename the method.

Benefits

Code is readable and explains what it does. Take care with your names and change them when you find better ones. Everyone who reads your code (including you) will be happier if you do.

Workflow

  1. Create a new method with a new name. Copy the code of the old method to it. Replace all the code in the old method by a call for the new method.
  2. Find all references to the old method and replace them with references to the new one.
  3. Delete the old method.

Step 2: Replace nested conditional with Guard Clauses

Problem

A group of nested conditionals make it hard to understand the code logic.

Solution

Isolate all conditions into separate clauses by using Guard Clauses. A guard clause is a snippet of code at the top of a function or method that returns early when some precondition is met.

Benefits

Function is smaller and the list of conditionals is flat. Guard clauses reduce complexity and make it easier to understand the logic. We are able to skip reading the guards and quickly see the primary goal of the method.

Workflow

  1. Isolate all clauses that lead to calling an exception or immediate return of a value from the method.
  2. Place these conditions at the beginning of the method, before the main checks.

Step 3: Replace hardcoded value

Problem

The code uses a hardcoded value that has a certain meaning to it.

Solution

Replace this value with a constant or a config parameter that has a human-readable name explaining the meaning of the value.

Benefits

Make it easier to change the value of a constant or the value of a config than to search for this value throughout the entire codebase, without the risk of accidentally changing the same value used elsewhere for a different purpose.

Workflow

  1. Declare a constant or create a config parameter and assign it the value.
  2. Find all mentions of the hardcoded value.
  3. For each of the values that you find, replace it with the constant or the value of the config. Make sure it is the correct value to replace.

Step 4: Remove duplicate conditional fragments

Problem

Identical code can be found in all branches of a conditional.

Solution

Move the code outside of the conditional.

Benefits

Code deduplication.

Workflow

  1. If the duplicated code is at the beginning of the conditional branches, move the code to a place before the conditional.
  2. If the code is executed at the end of the branches, place it after the conditional.
  3. If the duplicate code is randomly situated inside the branches, first try to move the code to the beginning or end of the branch, depending on whether it changes the result of the subsequent code.
  4. If appropriate and the duplicate code is longer than one line, try using an extracted method.

Step 5: Extract method

Problem

A code fragment can be grouped together.

Solution

Move this code to a separate new method and replace the old code with a call to the method.

Benefits

The method is smaller and easy to test. The code is more readable because the new method has a name that describes the method’s purpose. It can be reused elsewhere in the program. For example, the function can be used before to update the book.

Workflow

  1. Create a new method with a readable name that explains what the method does.
  2. Copy the relevant code fragment to your new method.
  3. Replace the fragment by a call for the new method.

Step 6: Extract variable

Problem

An expression is hard to understand.

Solution

Extract each result of an expression in separate variables.

Benefits

Make a complex expression more understandable with variables that have meaningful names.

Workflow

  1. Declare a new variable with a meaningful name for each complex expression . Assign the expression to this variable.
  2. Replace each expression to the variable.

Step 7: Consolidate parameters with an object

Problem

A method contains many parameters.

Solution

Create an object that includes the parameters.

Benefits

More readable. The method has an object with a comprehensible name instead of many parameters. It’s easy to add a new criterion without changing the method signature. It’s possible to use a validator for make sure that object is valid.

Workflow

  1. Create a new class that will represent your group of parameters.
  2. Replace the parameters with the object created.
  3. In all method calls, pass the object created from old method parameters.

Step 8: Replace Array with Object

Problem

An array contains certain elements mean different things.

Solution

Replace the array with an object that has a field for each element.

Benefits

The field of a class are much easier to document than the elements of an array. Indeed, it’s complicated to know which are all the array keys used to store the data instead of a class which has an auto completion thanks to the documentation. It also easier to test a class instead of an array. Each access method of the class could have its own logic.

Workflow

  1. Create a new class that will contain the data from the array.
  2. Create a private field for each element of the array.
  3. Create access method for each field of the new class.
  4. Create a new instance of the class in the place where the data array was initiated.
  5. Replace each element of the array with the access methods.

Step 9: Consolidate Conditional Expression

Problem

Several conditions lead to the same result or action.

Solution

Consolidate all conditionals in a single expression.

Benefits

Code deduplication. The multiple conditionals are now isolated in a new method with a name that explains the purpose of the conditional. The new method is easy to mock for testing the code.

Workflow

  1. Consolidate the conditionals in a single expression by using and and or .
  2. Create a new method with a readable name that explains what the method does.
  3. Copy the expression to your new method.
  4. Replace the expression with a call for the new method.

Step 10: Extract class

Problem

One class does everything at one place.

Solution

Extract each relevant functionality in separate class.

Benefits

The class has a single responsibility, this is the definition of the Single Responsibility Principle. The code is easier to test and maintain. It makes each class reusable.

Workflow

  1. Create a class for each relevant functionality.
  2. Move the methods that depend on this functionality in the new class.
  3. Pass object in the constructor of the class which depends on the functionality.
  4. Replace the methods by using the dependency.

--

--

Quentin Ferrer

I’m a french web developer. I develop in PHP with the popular Symfony framework.