To develop working, valuable software, we expend time and decisions. In this context, a good decision is one which helps us deliver more value with our time. When might refactoring be a good decision?

What's refactoring for?

I see refactoring, above all else, as a tool for managing risk.

Software development is naturally rich in risk. If we accept that it's worth doing, then we're accepting some amount of risk. For all but tiny projects, the greatest risks are likely:

  1. Making undesirable changes that go unnoticed until fixing them is surprisingly expensive
  2. Making desirable changes that seem worthwhile until implementing them proves surprisingly expensive

TDD can help us control (1) and — at no additional cost — affords us the option of refactoring, should we want to. And if we seek to control (2), I contend that we should want to.

Straw man: never stop refactoring!

Let's say we not only put stories whose only purpose is refactoring on the backlog, but we've got lots and lots of “refactoring stories”, and we prioritize them over everything else. We'll have maximized the number of possible future changes that are easy for us to make, but we'll never get around to making any of them.

Straw man: never start refactoring!

Let's say we not only don't ask permission to refactor, we simply never refactor. We'll have maximized how much time we're working on changes motivated solely by business value, but we'll have driven up two averages: the cost per change, and the risk of greatly underestimating the cost per change. Even if we accept that we've taunted Hofstadter's Law.

Who decides to refactor?

Illustration by Rebekka Dohme.
Make it work (bee sinuously finding way to target flower), make it right, make it fast (bees making beelines for target flower)

I see developers bee-ing best positioned to decide whether, when, and how to refactor.

I don't see that the “value” of refactoring and the “value” of software's user-visible behavior can be measured along commensurate axes. The latter is what we're here to do. The former is a way to improve our chances of doing it. The latter is best judged by the folks who rely on the outcome of what we make. The former is best judged by the folks who rely on the process of what we make.

When is refactoring a good decision?

If we agree that managing the risks of software development means mitigating its inherent variability while collecting just enough options along the way, then refactoring is likely a good decision when:

  • Developers choose it
  • Its intended scope is to clear a path in front of the desired change
  • Its intended effect is to deliver the desired change faster (or at least not much slower, and then to deliver future changes faster)

After some months of judicious and opportunistic refactoring (more or less depending on context), here are some trailing indicators that you're reaping the benefits:

  • You rarely wish an estimate didn't have to be so large
  • You almost never feel the need to fudge an estimate
  • You almost always get what you expected when you expected it

Conclusion

In software development, where risk management is a fact of life, refactoring is one of the most powerful tools at our disposal. Wielded wisely, it helps us more predictably deliver more value with our time.

References

My opinions generally derive from my experience (and, stubborn as I am, little else). The expression of this particular opinion is better for my having encountered the following expressions:

”If you want to estimate little things, you have to refactor.” — J. B. Rainsberger. 7 minutes, 26 seconds, and the Fundamental Theorem of Agile Software Development (Øredev 2013).

”Why refactor? Economics.” — Martin Fowler. Workflows of Refactoring (OOP 2014).

”Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.” — Douglas Hofstadter. Gödel, Escher, Bach (1979).

”Do not taunt Happy Fun Ball.” Saturday Night Live (1991).