Roman Imankulov

Roman Imankulov

Full-stack Python web developer from Porto

search results (esc to close)
26 Jul 2022

Opportunistic Refactoring

You know developers solve business problems with code. Taking this literally, you are so busy working on new features that you often find yourself making implementation shortcuts. Under the pressure of the product team, you don’t have time to get back and clean it up.

You know, in the long run, this is not sustainable. Shortcuts of the code inevitably make product quality degrade. Still, while evident in hindsight, the idea is hard to sell to product folks.

So, what can you do about it? I found that opportunistic refactoring works great to balance product work with tech debt elimination.

I learned about the techniques and borrowed the term from the brilliant deck Workflows of refactoring by Martin Fowler. I noticed that I usually share this presentation early as I join a team.

Opportunistic refactoring techniques combine the product work and address the tech debt

The general idea is that you don’t separate product work and refactoring. Instead, you do refactorings in small steps as you work on the feature. Marting Fowler outlines three techniques. The context starts when you’re working on a feature:

Litter-pickup refactoring. When you come across an ugly piece of code or a suboptimal pattern, you clean it up. Sometimes, it’s referred to as the boy-scout rule: “Always leave the code better than you found it.”

Comprehension refactoring. Often, you must figure out what current code is doing more than working on the change. As you build a mental picture, spend some time moving that understanding back into the code. It would be easier to figure out next time for you or your colleagues.

Preparatory refactoring. As summarized by Kent Beck, “for each desired change, make the change easy (warning: this may be hard), then make the easy change.”

Does it work for your own code? It may sound that you do litter-pickup or comprehension refactoring for the code written by others. I found that very often, I use these techniques for my proper code, even for the code that I wrote relatively recently — maybe, just as recent as a few weeks ago.

It may feel that refactoring slows down the progress. As someone who tried it once and then embraced it, I assert that the opposite is true. The benefits of constant refactorings are noticeable even in the short run. In the long run, their accumulated positive effect is getting even more prominent. Introducing a culture of small and constant changes makes engineers happier and reduces friction between product and engineering teams.

Things to read

Roman Imankulov

Hey, I'm Roman, a full-stack Python web developer.

If you like what you read and want to work with me, drop me a line to

About me