Refactoring is a Development Technique, Not a Project
Editorial note: I originally wrote this post for the NDepend blog. Go check it out over there and stay for a while to look around. If you like posts about code analysis, metrics, and the business of software development, you’ll like the collection of posts there.
One of the more puzzling misconceptions that I hear pertains to the topic of refactoring. I consult on a lot of legacy rescue efforts that will need to involve refactoring, and people in and around those efforts tend to think of “refactor” as “massive cleanup effort.” I suspect this is one of those conflations that happens subconsciously. If you actually asked some of these folks whether “refactor” and “massive cleanup effort” were synonyms, they would say no, but they never conceive of the terms in any other way during their day to day activities.
Let’s be clear. Here is the actual definition of refactoring, per wikipedia.
Code refactoring is the process of restructuring existing computer code – changing the factoring – without changing its external behavior.
Significantly, this definition mentions nothing about the scope of the effort. Refactoring is changing the code without changing the application’s behavior. This means the following would be examples of refactoring, provided they changed nothing about the way the system interacted with external forces.
- Renaming variables in a single method.
- Adding whitespace to a class for readability.
- Eliminating dead code.
- Deleting code that has been commented out.
- Breaking a large method apart into a few smaller ones.
I deliberately picked the examples above because they should be semi-understandable, even by non technical folks, and because they’re all scalable down to the tiny. Some of these activities could be done by a developer in under a minute. These are simple, low-effort refactorings.
Let’s now consider another definition of refactoring that can be found at Martin Fowler’s website.
Refactoring is a controlled technique for improving the design of an existing code base. Its essence is applying a series of small behavior-preserving transformations, each of which “too small to be worth doing”. However the cumulative effect of each of these transformations is quite significant.
I took the wikipedia definition and used it to suggest that refactorings could be small and low-effort. Fowler takes it a step further and suggests that they should be small and low effort. In fact, he suggests that they should be “too small to be worth doing.” That’s fascinating.
The All or Nothing Fallacy
Why do you think Martin Fowler would say this? It’s a paradoxical statement — encouraging people to do things that are not worth doing. And yet, there’s a powerful message being relayed here: “refactor, even when you think it’s not worthwhile, because refactoring toward clean code is a war of attrition.”
What Martin Fowler is rebelling against with this phrasing is what I’m calling the all or nothing fallacy here. And that fallacy is what causes the conflation between “refactoring” and “massive cleanup.” It’s the idea that cleaning up a code base happens in massive batches or it doesn’t happen at all.
Refactoring as House Cleaning
Think of the approach most take to having a clean house. The house naturally tends toward dirtiness unless counter-measures are taken, so there needs to be a “clean house plan,” if you will. Some people maintain a strict and rigid set of policies to keep the house clean: no shoes in the house, food only in the kitchen, etc. If you stick to this discipline, the house will remain clean. There’s never any massive effort occurring, but the house stays clean through a constant series of “micro-efforts.”
On the opposite end of the spectrum, consider a house that’s utterly disgusting. The inhabitants eat food anywhere and throw the garbage on the floor when they’re done. No one ever dusts, vacuums, scrubs, or cleans in any way. People walk into the house with muddy shoes without a second thought.
Now imagine that you’re brought in to help turn the disgusting house into the spotless house. You can’t simply declare the disgusting house condemned and move the inhabitants — you have to stay with the same house and the same people. Naturally, you call for some pretty extensive cleanup. But that cleanup never happens.
The reason it never happens is because the slobs, for all of their poor house maintenance, have lives and jobs. They have things to do. They can’t simply take weeks off of work to declutter the house, prepare for carpet steam cleanings, re-grout the bathroom tile, etc. You call for massive cleaning and they look at you, saying, “sure, that’d be nice, but we live in the real world.” If you suggest that they do little things to help, they fatalistically ask, “what’s the point?”
Expectations for Cleanup
Martin Fowler is saying to these people, “spend 10 minutes a day doing cleanups that are too small to matter. Do it every day, like clockwork, and, after enough time, you’ll start to see results that actually matter.”
He’s right about the house, and he’s right about code. Refactoring is not a 3 month break that you take from delivering anything of value, so that you can “clean up.” Refactoring is a series of tiny decisions that you make in your code base that add up to big value over the long haul. It’s the equivalent of spending 40 years putting your spare change into a piggy bank that goes into a retirement account.
So when I’m asked by managers and CIOs whether they should stop work for a while and spend a bunch of money on a cleanup, my answer often surprises them: “of course not.” “Your developers,” I tell them, “need to learn to keep the house clean on a daily basis before a massive cleanup can be sustainable.”