get in touch

How to stop finding time for refactoring

Anton Kalinin, CEO at MadAppGang
Anton Kalinin

It seems to me that we hear a lot about refactoring, and the number of questions about it is increasing, not decreasing. Today I'm going to talk about it from my own experience. I've been a programmer for 13 years and have seen a lot of different projects.

First, let's clear up what refactoring is once and for all because the question "How do I find time for refactoring?" often leads to misunderstandings.

Meme with a dog in a hat paints a picture on an easel in a burning room telling "Now is definitely time for refactoring"

Instead of trying to convince a product manager to allocate refactor time, change perspectives. You don't need dedicated time for refactoring because you can look at the process differently. 

A fresh perspective

Some think that programming is all about making code that works. That's partly true, but it's way more than that.

Programming is about handling a constantly changing code base. It's about meeting specific requirements today and being ready for new demands tomorrow. It's about communicating clearly across space and time with other developers who will read, modify, and expand your code. 

Programming isn't just about writing functional code. It's about writing code that's easy to read, understand, and modify.

Rethinking ‘done’

Getting code to work is a must, but it's not enough. In test-driven development, we have the red-green-refactor cycle.

The red-green-refactor cycle of continuous refactoring

Functional code involves the red and green stages, making sure the tests pass. But refactoring is about the last step, making sure the new code is understandable and maintainable.

A guy in a red jacket stands on a ladder at a height where there are a lot of tangled wires and says that after we add a new feature, we're sure to refactor it.

This is where the mindset shift comes in. As developers, we shouldn't just consider our work 'done' when the code works, but when it's easy to understand and modify.

Refactoring should be ongoing. You shouldn’t need to schedule specific ‘refactor time’ because it's built into the essence of our work.

Decoding refactoring

Some people worry that refactoring always involves huge, complex changes. But that's not the case. At its core, refactoring is about changing code structure without altering its visible behavior. Check out this definition from the Refactoring book:

Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

While we work, we should always strive to improve code without changing its behavior, making it more understandable and easier to change.

Maniac with a chainsaw and an inscription "Code refactoring time"

When to refactor

Refactoring should happen continuously. We can refactor according to an American Boy Scouts principle: If we see garbage, we clean it up. 

‘Deciding’ to refactor isn't the point. We refactor because it helps us achieve something else. As Martin Fowler puts it in ‘Refactoring: Improving the Design of Existing Code’:

You don’t decide to refactor, you refactor because you want to do something else, and refactoring helps you do that other thing.

In practice, there are three situations when I refactor: 

  • as the final step in the red-green-refactor cycle
  • when facing unclear code
  • when the existing design doesn't fit. 

Let’s take a closer look at each situation.

The final stage of red-green-refactor

As mentioned earlier, the red-green-refactor cycle already includes refactoring. So, when I get successful tests, I spend a few minutes cleaning up any new code: giving more explicit names, extracting private methods, creating new classes, and so on.

Unclear code

Meme with a character in The Big Bang Theory sprays a spray can near him

When I try to add a new feature or fix a bug and I need to modify existing unclear code, I start refactoring (once I understand what it does). This ensures I make the right changes to the codebase and make it easier for future developers (including myself) to understand. We should pay the price of hard-to-read code once, not every time it’s read.

Errors are like cockroaches, they like to live in the dark, musty places in your code. Tidy up your code and bugs will find themselves exposed in the open. And you won't have to create particular refactoring tasks that managers don't like to see in reports.

Incompatible existing design

Finally, I refactor when introducing something new that clashes with the existing design. I first refactor the design to easily accommodate the new element. This aligns with Martin Fowler's idea of reparatory refactoring:

When you find you have to add a feature to a program, and the program’s code is not structured in a convenient way to add the feature, first refactor the program to make it easy to add the feature, then add the feature.

Or, as Kent Beck said:

The screen shot of Kent Beck's post in Twitter

Level up your refactoring skills

If you want to practice refactoring complex code, I recommend the Gilded Rose Kata, a really cool and enlightening exercise.

And most importantly, I highly recommend diving into Refactoring, the book mentioned above. It's packed with valuable information about how, when, and why to refactor.

Remember the main rule: regular code refactoring during product development is much smarter and more cost-effective than dealing with problems that arise from a lack of such an approach.

P.S. To help you transform your digital infrastructure into a reliability powerhouse, here are some tips on how to adopt Site Reliability Engineering (SRE).

Meme with a superhero who can't decide which button to press - Refector the code or Rewrite the code