Think refactoring and I'm guessing most people have a scenario like this in mind - it's the daily standup. One of the devs grabs the talking stick and says "There' s a problem with the interface code, there is too much tech debt so I'm going to have to refactor. it will take me the rest of the sprint so we will have to re-plan the feature to next sprint". Everyone grumbles, the code is checked by the leads and yes, it is a mess so we do need to spend a sprint refactoring and the date of the release gets pushed back. Or the decision is made to defer the refactoring and just hack the new feature in to meet the date, thus further increasing tech debt.
The thing is, that's not refactoring. That's re-writing chunks of code because tech debt has built up to intolerable levels. That is a slow activity. That's not what refactoring is. Refactoring is making constant small changes so that tech debt never builds up in the first place. What does good refactoring look like? The best way I can explain it is to take you out to lunch to a really good sushi restaurant.
While we are eating, spend 5 minutes watching the chef. Hands moving like lightning, deftly assembling the sushi and arranging it on plates. Slicing whole fish into delicate slices. Preparing vegetables and rice. Amazing to watch. Now look at her workspace. What do you see about it? She has been working there all day non stop, assembling sushi at lightning speed and the workspace is spotless. Everything clean. Every tool exactly in its place. No waste lying around. Where does she find time to clean up? And how does she maintain such a fast pace if she wastes time cleaning?
Take a close look at what she does. Watch her hands - slice some fish, stack the slices neatly, wipe the knife put it away, wipe the surface, grab another knife, slice some cucumber, stack the slices neatly in their place, wipe, put away, assemble some rolls, arrange on plate, wipe, clean, grab the fish knife, skin the fish, scrape the skin into the bin, wipe, slice, wipe, scrape, slice, assemble, wipe. And so on.
The workspace never becomes messy because she is cleaning as she goes. After every step she takes a couple of seconds to make sure the workspace is spotless and well organised so the next step can be performed effortlessly. She knows that the few seconds spent cleaning and putting away after one step mean that rubbish doesn't build up and make the next step harder. Cleaning is not an impediment to speed. It's an enabler.
I do the same sort of thing in my own workshop. I clean up after each step to make sure my bench is clean. That way when I put a nicely finished piece of timber on it, I'm not putting it down into a pile of shavings from the last step and grinding them into the nicely finished surface, leading to rework and cursing. I make sure I touch up the edge on my tools as I go, so I don't need to spend hours laboriously re-grinding the edges because they have become damaged. Sharp tools also cut faster and cleaner so a few seconds touching up the edge will save a lot of time later (and potential damage when my blunt chisel tears something, rather than cutting cleanly, leading to rework and cursing).
A clean workspace is efficient, easier to use, faster and safer. That's what refactoring is. It's cleaning as you go. Making sure you can find your tools. Making sure they are in good repair and ready to go. Making sure materials are stacked in easy reach and are kept safe from damage. Making sure the bench is clean.
In software, your code is your workspace. Refactoring is cleaning your workspace as you go to make sure tech debt never builds up in the first place. Every time you finish something, take a few seconds to clean as you go. Make sure the workspace is spotless so you can perform the next step effortlessly. If you want to move fast, refactoring isn't an impediment. It's a requirement. You can't move fast in a messy workspace.
Proper refactoring you should never hear about in the daily standup. If you have to mention that you are spending significant time refactoring, it's a sign that someone hasn't spent enough time cleaning as they go. Often, in large organisations with established legacy code bases, that someone will have left the organisation years ago and the current team will be stuck with their mess. Dealing with that legacy may well involve some significant effort. The important thing, though, is that we shouldn't let the fact that the old code is messy stop us from making our new code clean. We should still clean as we go for all new code; that way we don't make our problem worse. After all, when you are at the bottom of a hole, the first thing to do is stop digging it deeper.