Why you no?! — Iterative Refactoring

Chris Klapp
5 min readFeb 8, 2022

--

As a programmer it’s easy to be passive agressive with our code. We wait until we can’t stand our code and it makes us sick to our stomach before we consider it. Refactoring doesn’t have to be done as a major single effort that is done infrequently. Instead, refactor interitively and continuously.

https://imgflip.com/i/64fqa8

Always be refactoring

There are many things you can do to practice continous and iterative refactoring. Here are a few things that you can try out.

  1. Keep things tidy: leave everything better than you found it.
  2. I did what?!: use git blame for good.
  3. Test driven refactor: use tests to confirm you didn’t break everything.
  4. Less is less!: use small changes for less technical debt.
Refactoring can feel like finding hay in a needle stack when we wait too long.

Keep things tidy

Over time we develop our skills as programmers and improve our knowledge of best practices. Best practices change and so should our ability to code. When you revisit a codebase to add a feature or fix a bug, we should look for things to improve every time.

Most of the refactors that I’ve done through the years have been made up of a lot of little things. Many of them could be handled quickly individually. It has always been easier to iteratively refactor my Proof of Concepts and Prototypes as they are typically smaller and easier to work with. My goal is to share the joy I find when I am always in the state of refactoring.

It’s so much easier to keep a house clean than it is to clean it once a year. If it only takes a few minutes to clean up the offending code smell, why wait until it cascades out of control? Every time you edit a file, look for something to pick up. Then when it comes time for an architectural refactor, it isn’t as overwhelming.

I did what?!

Git blame is a powerful tool that is commonly used as an accusatory weapon. It’s so much more than that. It’s a great tool for figuring out the context of the changes that evoked those lines of code. More importantly it can help you know who you need to talk to if you don’t understand why something was done that way.

While working on an issue, I frequently scratch my and wonder why things were done a certain way. I’ll use Git blame to figure out who to get more details from, only to find out it was me… a couple of years ago. I tell myself it’s a good thing, a sign that I’m getting better! Sometimes it would be easier if it was somebody else. That way I can reach out to them and collaborate on a way to make things more readable and maintainable.

Try to use Git blame to get more information about code you have questions about. If you don’t know how to use the command line for it, use Github. Just open the repo/file on Github, click the line number in question, then the three dots beside that, and then select “View git blame” for the who and the commit link.

Test driven refactoring

We’ve all heard of TDD or Test Driven Development. What about TDR? Test Driven Refactoring can help us ensure we didn’t break things while we refactor. Yes, this adds time to our refactor, but helps us iteratively add tests to improve our test coverage. Try this the next time you make changes to your codebase, you also have a better chance of not accidentally breaking something.

At the start of my current refactor, I was guiding another developer through my thought process. At first we weren’t sure what we could divide and conquer. We realized that we could do something in tandom. One of us could write tests and the other could refactor. Once we are done we will ensure that the refactor passes tests that work off of known good.

Pair programming during a refactor can be quite difficult. Assigning one dev to write the tests and the other to refactor, can help both be productive without stepping on each others toes in the process. Combine that with continuous and iterative refactoring and you are continuously and iteratively increasing your test coverage. Your QA team will thank you.

Less is less!

Less is less! Less long term frustration. Frustration that comes from piled up technical debt. Less long code reviews for those large refactors. Less time in spent needing to explain or get help. Less breaking of functionality as it is easier to test. Less long meetings planning large releases.

I commonly fall into the trap of making tons of small changes at once and pushing them through to QA. It sounds counter productive to have more releases (you got me to say less is more) but bundling a lot of changes in a release have always lead to longer release cycles that cascade out of control. In the end continuous iterative releases, whether it’s new features or small refactors, mean less time overall.

Once we get started implementing a best practice or cleaning up our code it’s hard to stop. Then we run into huge cumbersome peer reviews of our pull requests. To combat this try to address one thing at a time. Make your commits small and meaningful. Make your pull requests small and meaningful. Less is more, more or less.

I’ll be honest and admit that I don’t always follow these as strict rules but I usually regret when I don’t. Maybe that’s why I started writing this series, to help reinforce the patterns that worked well in the past and avoid the ones that caused problems.

If you want to read more about my perspective and thought process on refactoring, read my previous post, Code Smell — When to Refactor.

--

--

Chris Klapp

Research & Development specializing in ML and NLP. Values team buy-in, thinking outside of the box, and solving seemingly impossible problems.