Seven tips you always wanted to know about refactoring

Introduction

Technical debt is a persecution that sooner or later, at various levels, we are all forced to address. You too will surely have found yourself looking disheartened at your monitor, staring at incomprehensible code produced who knows when, under who knows what premises and conditions.

If you are a human being, your first thought was to wish you were elsewhere.

Your second thought, however, was probably to start refactoring, that is, a total or partial rewriting of the code to improve its quality.

If only you had the time to do this. Because you too will be under similar conditions of unclear and unstable specifications, with an imminent important release, under pressure, always chasing after the next feature.

You would like to take a few days to improve the code but you can’t. So what next?
Here are some tips that could help you in this common situation.

1. Lower your expectations

The purpose of refactoring is not to have nice code straight away, it is to obtain code that is better than before. Essentially fragmenting a large refactoring into many small self-contained interventions that are objectively improvements and that will help you to decrease your technical debt.

Over time you will see that incomprehensible pieces of code, which would have taken days of work just to be decoded and corrected, will become less and less frightening.

My incremental checklist includes:

2. Two-minute rule

A refactoring intervention should be conclusive within a few minutes. Any more time-consuming interventions should be broken into smaller, self-concluding interventions, if possible (and very often it is).

Two minutes to improve the name of a class, or to eliminate a piece of dead code, can always be found.

Refactoring therefore becomes a daily process instead of an extraordinary activity to plan and to be decided with management.

3. Keeping clean is easier than cleaning

Try, if possible, to curb technical debt in input. No refactoring can save you if the speed with which the code degrades is greater than the speed of improvement, and in this case it risks becoming a huge waste of time.

Improving the code is a process that, when started, requires a certain level of discipline from the whole team.
A very effective tool in this sense is the practice of code-review to identify problems and code-smells.

4. Think about the long run

The fight against technical debt is not a sprint but a marathon. Code slowly deteriorates over time, day after day, commit after commit and in the same way it can improve.

If you can block the incoming technical debt and at the same time achieve a few dozen improvements per week, the results will be visible very quickly.

When, iteratively, the names of variables, functions and classes improve, the dead code disappears, the size of classes and functions decrease, and so it becomes progressively easier to read and understand the code over time.

Improvements that would require hours of work today become easier and less expensive.

5. Use advanced tools and IDEs

To be able to close an improvement cycle in a few minutes it is important to have tools available to help you to achieve this. In particular:

6. Architectural interventions apart

Architectural refactoring is the most complicated and the most difficult to break into simpler refactoring. For this reason it is important that all the cleaning work has been performed before addressing architectural elements.

Try never to mix small code cleaning operations (renaming classes, variables, extracting functions, the removal of unnecessary code and comments, etc.) with architectural interventions (communication between components, abstractions, etc.).

Also remember that the latter require that the direction of refactoring has been discussed and approved by the entire team. In fact, all team members must be aligned on what needs to be changed and which design we are going to use.
Ideally these decisions should be written in a supporting document so that they are not lost in development.

7. Automatic tests

Put yourself in a position to be able to write automatic tests quickly and, at least for all new developments, be sure to test the various components. This will greatly assist the refactoring process and help you control stress. The key word is always incremental progress.
Even writing one test per day (which requires very little effort) over time you will find yourself a full-bodied suite.

Conclusions

Using the divide and rule approach, you should be able to reduce the technical debt a little at a time, through a constant series of small interventions of a few minutes.

This should help you build a day-to-day improvement process that will become more significant over the life of the project. All this should be accomplished, as far as possible, in iterations of just a few minutes that do not require special authorisations or alterations in the planning of deadlines.

Refactoring thus becomes a constant, daily process, to always be combined with normal development activities.

Photo by Tim Gouw on Unsplash