When it comes to refactoring code should we Tidy First?
Menilek Techane

Menilek Techane @menilek

About: Full Stack Software Engineer with 7 years of professional experience. Currently working to enhance the detection of heart disease

Location:
Birmingham, UK
Joined:
Dec 30, 2018

When it comes to refactoring code should we Tidy First?

Publish Date: Nov 28
0 0

At work in my team we didn’t have an agreed upon approach to refactoring. Therefore, the question of how, when and why we refactor was left up to us which can lead to inconsistency and large Merge Requests (MRs) at a minimum and utter despair and destruction bigger issues that I’ll leave you to imagine😉

I recently read an informative book on the subject of refactoring called Tidy First by Kent Beck. Kent refers to a range of refactoring techniques which he calls ‘tidyings’ and argues that we adopt them as a form of ‘geek self care’ over the 122 pages of the book. The most pertinent part of the book concerning us, questions when should we refactor?

Tidy First? By Kent Beck

Before we discuss when and why, it is important to understand what kinds of changes we can make regarding refactoring aka tidying. Changes to a codebase can largely be split into either behavioural changes or structural changes. Behavioural changes are your feature requests and fixes which extend a system. Structural changes however, seek to maintain the existing behaviour within a system but augment the structure oftentimes for our own benefit.

For example, we may reorganise the order (aka flow) of code within a class/component/file to better aid our understanding. It is these structural changes that we are concerned with when we talk about refactoring. With this distinction in mind, let’s now address the when and why.

Consider the scenario where we are faced with introducing a feature request to an existing Platform system (remember this is a behavioural change). Let’s say we see some issues with the codebase whilst attempting to introduce this new behaviour. Maybe we notice that the functions we plan to extend lack types. Should we tidy first? In this scenario, the payoff is immediate and you know exactly what to do and how. Changes of this nature are like keeping the kitchen clean as we cook. This example is a no-brainer, of course we should tidy first - notice the change is small and can be completed immediately, unlike introducing typing across all functions in the repo (I’m guilty of this😅). Essentially, it is advisable to tidy first if it will make the behavioural change easier.

Untangling mess

Tidying after making a behaviour change is a good option when tidying first doesn’t make sense. This may be because the code is quite tangled or complex so by making our change first, we’d gain a better grasp of how we could improve the structure. This is all dependent on the scale of the change(s). Kent Beck advises that we can tidy after, if the refactoring's are proportionate to the behavioural changes. For example, a 30 minute behavioural change would solicit a 30 minute structural change at a maximum. This seems very generous to me (especially when we consider bigger behavioural changes spanning days) but as a rule of thumb I’d advise that refactoring’s are smaller than the time taken to implement behaviour.

Kent goes on to argue that we should seek to tidy after a behavioural change when coming back later would be too expensive or if you wouldn’t feel a sense of completion submitting the work without this tidying. This would produce an MR combining a behavioural change with a moderately sized (at best) structural change.

The third option is to tidy later. This case is fitting when there is a big batch of changes required that offer no immediate payoff and would be better suited to a separate Merge Request. To phrase this another way, you can tidy/refactor in small batches and there is eventual payoff. Once I pushed a change to introduce types to functions across the board which added additional complexity to an MR I had raised. This was a big batch of changes with no immediate payoff. I was encouraged to instead document similar issues in a ticket to come back and make such a change later which prompted me to write this!

Sweaty developer

The final option is to tidy.. never! This is only appropriate when you’re never going to change the code again - for instance, we have some retired repositories that are unlikely to change. This option is reserved for the smallest number of cases as the majority of code we work with is living and changing which leads us to consider how we will agree to approach and apply the three former methods of tidying.

After reflecting on the above, I created the following proposal for my team:

  • An MR can include small ‘tidyings’ that offer immediate benefit. These may be introduced before or after the behavioural change of a feature/fix ticket.
  • If the structure change does not offer immediate benefit or is not related to the current behavioural change it can be documented in a ticket to be addressed later.

I’d love to hear your thoughts on this! How do you (and your team) handle refactoring code? Thanks for taking the time to read this🤓

Comments 0 total

    Add comment