We usually talk about refactoring code with the same kind of pedantic approach we do with all other kinds of software writing. We come up with recipes to abstract, break apart, and clarify. We fold these techniques together into larger ideas and catchier names like the Mikado method, the Big Bang approach, divide and conquer, or strangulation. OK, maybe not all of them are catchy.

But, with all these strategic tools in our belt, a big refactoring still requires a tremendous amount of mental stamina and perseverance. In fact, what really makes it difficult has more to do with our own psychology than it does with the shape of the code itself.

In most big refactorings, we don’t have the luxury of a complete rewrite. Features need to be built; bugs need to be squashed. Our only option is to push in-flight production code toward a new direction gradually. We make small changes continuously, seizing opportunities to remold portions of a system when the time is right.

And therein lies the rub. Rehabbing code that still needs to serve its customers often requires some extra weight to allow the new code in, while still holding onto the old code we’ve yet to clean up.

A refactoring might necessitate creating ephemeral objects and methods solely so we can fit the old temporarily with the new. While these extra pathways are being created, the code will feel like it’s bulging at the seams—because it is. A big refactoring is rarely as hygienic as swapping an ugly piece for a pretty piece. It often means putting in a whole lot of intermediate structures; the ugly-but-necessary scaffolding to keep our patient able to work on his daily chores while still under the knife.

In any big refactoring, you have to cope with two dissonant ideas: trying to make a codebase better and the reality that—in the midst of it, the code may actually feel a whole lot worse. This is, perhaps, the real reason that the whole process feels daunting. Every decision in a refactor weighs the short-term pain with the future payoff. And, often, the short-term pain convinces us that today is not the day to begin.

However, once you’ve accepted this, a big refactoring becomes a lot more tolerable. You aren’t fighting the devil on your shoulder who wants to scold you for the off-course moves you’re making now to get to tomorrow’s pot of gold. Eventually, we reach that glorious day where the old abscesses can be completely removed and our new code is in full control. But, until then, the battle is as much in our minds as it is in our code.