In my experience there are two kinds of refactoring, the littering kind that this article talks about and the infrastructure kind. I completely agree on the littering kind, for each change a developer makes they should clean up any litter they find and not leave any additional. I’ve also found this to be a very infectious thing — clean codebases tend to stay clean and littered codebases tend to get worse. (Arguably just because clean codebases has someone enforcing it).
The infrastructure kind, which is largely due to an abstraction that misses the mark, is a much more involved endeavor and requires dedicated effort to overhaul. However, it can be easy to mistake a codebase littered with garbage as requiring an infrastructure change (and thus overhaul) when the abstractions are actually sound.
However, there is an argument to be made that any codebase will eventually have infrastructure issues. It’s hard to get every abstraction correct the first time. So spending time cleaning up litter on a codebase that will need an overhaul is time wasted. Keep the well-travelled paths clear, but does it really matter about the rest?
There are tradeoffs when it comes to litter; for a PoC it simply doesn’t matter, but as we all know every PoC has a large chance of going into production. It feels like we need better terminology and ways of talking about the tradeoffs we’re making and the constraints of the organization/engineers we’re working with.
I agree with the title of the article, but the article itself doesn’t argue on the tradeoffs and more argues it’s never good to have litter because there is a cost to litter. While I love working in litter-free codebases, I understand those who don’t care as much as seeing different tradeoffs involved.
This would be a good blog post.