Every once in a while, I ask someone whether they refactor their code. The reaction I get is hard to describe. Often within the span of a few seconds, I see the inward smile that says "Of course, I do" followed by the sad expression that says "Not as much as I should." Many times, those two micro-reactions are followed by "Oh my God, I don't want to think about the state of my code right now", or "Are you picking on me? I'm doing the best that I can."
I think there is a reason why this happens. We haven't been very good about settling the place of refactoring in software development. As a result, the practice is usually sloppy -- hit or miss.
The advice that most people get about refactoring is to do it as you go. And, frankly, if everyone did that, the state of many code bases would be much better. The reality, though, is that developers often see it as a less important activity. It doesn't seem like it has any immediate gain, so it is easy to short-change it in the face of a heavy workload. The natural response to this would seem to be scheduling time to refractor, but traditionally many organizations are reluctant to do that because (again) it is hard to see the payoff. Most of us have a story about a "refactoring iteration" that went wrong -- at the end the organization was unclear what benefit they received from it and/or upset that they accepted a lull in feature delivery. Refactoring "stories" don't have a good reputation either -- the ROI is unclear and there's always this nagging feeling that they would not be necessary if we all practiced "refactor as you go."
So, refactoring is sloppy. What can be done?
Well, there is a good path forward, but it involves doing something counter-intuitive. We can introduce a "hand off" in development. Here's how it works. For every story/feature that you accept in planning imagine how you would implement it if the code was in a state where it would accept the feature easily. Then, create a task for that refactoring work and make sure it is done before the other tasks for the feature, and (here's the trick) it should not be done by the whomever is going to do a feature addition task on the same story.
Here's the rationale. Breaking out refactoring at the task level highlights it. It's easier to focus on refactoring as as team when it is seen as separate activity. Having an hand-off between people the people who are doing the refactoring and the people who are doing the feature addition forces a degree of scrutiny and communication that is hard to have otherwise.
Like anything else in process, this is medicine. It's not meant to be "the way that people do things for all time" but rather as a way to raise the visibility of refactoring within a team, or to make deliberate progress toward some longer term refactoring goals.