Why Refactoring Does Not Mean a Complete Overhaul?

It is ok to take small steps to improve the design of your code

Why Refactoring Does Not Mean a Complete Overhaul?
Take small steps while refactoring, Photo by RetyiRetyi on Pixabay

During a recent conversation with my co-worker Tom, we discussed the importance of refactoring code to make it more maintainable and extensible. Tom mentioned that he was planning to refactor an entire library before adding a new feature and that the refactoring process would take several days.

I was curious about Tom’s decision to refactor the entire library and asked him how he determined it was necessary. Tom explained that he wanted to be proactive and “defensive” in his approach, by anticipating future changes and making the library more adaptable to those changes. He felt that by refactoring the library now, he could avoid potential problems and save time in the long run.

I disagreed that we had to refactor this library completely. Refactoring only a part of the library would improve the code and would lower the risk of breaking existing functionality.

For me, refactoring consists of taking small steps. These steps could be very small. Let me give you an example of what I see as a small step.

Two classes contain almost the same functionality in the library we were discussing. A clear violation of the Don’t Repeat Yourself (DRY) principle and a refactoring candidate.

A small step would be to move the two functions closer together. Extract a method from one class, copy it into another, and change the callers. That would be it. The code would be better and easier to change because you are less likely to forget to change the other function. Let me show you the code for a complete picture.

We have two methods in different classes. The first parseMedia, which you can see below. This method is in the VideoDbBuilder class and parses an incoming JSON file with movies and saves them in a local SQLite database. The class is part of an app that runs on Android Tv.

The second method has the same signature and is called parseMovies. This method is part of the MovieManagement class.

Both methods have the same signature and share a lot of functionality. Clearly, these classes and methods should be refactored. My proposed refactoring was to move the parseMovies method into the VideoDbBuilder class and change the calling code to use the VideoDbBuilder class instead of the MovieManagement class. This way, both methods would be closer together.

Tom disagreed. He said that this was not following the camping rule. The camping rule is from “Refactoring Improving the Design of Existing Code” by Martin Fowler. It states.

When programming, follow the camping rule: Always leave the code base healthier than when you found it.

I disagreed as the codebase was healthier after the change.

I decided to re-read parts of the refactoring book to see if there was an answer. I asked if Tom could do the same.


Refactoring Improving the Design of Existing Code

I completely re-read the second edition of “Refactoring, Improving the Design of Existing Code” by Martin Fowler. The book describes refactoring as a noun and as a verb. The book describes the verb refactoring as:

Refactoring is the process of restructuring software by applying a series of refactorings.

The book describes the noun as:

A Refactoring is a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

I was most interested if there was something in the book that describes the size of a refactoring. The first 40 pages of the book demonstrate refactoring. It optimizes an application that calculates and creates the invoices of a theater company. It uses a couple of refactorings patterns from the book.

Although the example sometimes took small steps, such as renaming a variable, it needed to indicate the optimal size of refactoring.

The book's second chapter looks at some of the principles of refactoring. It contains an interesting quote.

If someone says their code was broken for a couple of days while they are refactoring, you can be pretty sure they were not refactoring.

A little bit further in the same chapter on page 51, it states.

The nice thing about refactoring is that I don’t break the code with each small step, so, sometimes it takes months to complete the job but the code is never broken even when I’m partway through it.

Further, on page 52, Martin Fowler says he is reluctant to have a team do dedicated refactoring. He describes this useful strategy.

A helpful refactoring strategy is to work on the problem over the course of the next few weeks. Whenever anyone goes near any code that’s in the refactoring zone, they move it a little way in the direction they want to improve.

The rest of the book describes various refactorings. One of the interesting refactorings was “Move Function”. The move function is the refactoring I described in this article's first part.

Another interesting rule was the Rule of Three which indicates when to refactor. It states.

The first time you do something, you just do it. The second time you do something similar, you wince at the duplication but you do the duplicate thing anyway. The third time you do something similar, you refactor.

Re-reading the book’s second edition gave me the answer I sought.


Going forward, refactoring guidelines

After re-reading the book, Tom and I discussed what we found the most interesting. Based on our findings, we created refactor guidelines that we could use as development team.

We came up with the following.

  • Refactorings should be small and should never break existing code.
  • Always follow the camping rule. Leave the codebase healthier than when you found it. The change can be small.
  • We are not going to create refactoring stories. Refactoring should be part of a typical developer routine.
  • If we need to refactor a large part of the system or a library, we make it a team effort. Whenever anyone goes near any code in the refactoring zone, we move it a little in the direction we want to improve.

Currently, we are using these guidelines. We will constantly refine them if needed. I will let you know how it goes. Thanks for reading, and always remember to continue learning.

What about you? Do you use guidelines for refactoring? If so, which one?