In more than one project retrospective, I’ve heard things like “We need to slow down so we can refactor more and write better code” and “We need to be more disciplined about writing good unit tests.” New Year’s resolutions to “be better about X” rarely last more than a couple days, and the resolutions we make at the end of projects too often are the same.
Sometimes when you end up there, it really is a lack of discipline, and you just need to get the whole team to buy into some refactorings. But more often than not the reason you need to refactor is because you’ve discovered parts of your business domain that are not modeled well in your code.
The smell to look for is lots of special-case code:
* big switch statements
* many classes that are subclassed so one method can be specialized
* some sort of override functionality in your views
Those are just a few things I’ve seen on projects before, but this is probably one of the most common issues I’ve seen in retrospectives: “We learned more about the domain but didn’t have time to update the code.”
The dangerous thing about that lesson is that it never gets fixed: You can’t just summon more time or discipline, and things aren’t going to change next time around. If you try to buffer your estimates more next time, all that means is that you’ll have a really impressive velocity at the start… and then end up with code that still has lots of special cases.
Instead, try to focus on the user-facing pieces and use this as motivation to do more research. If your code is not a good model of the problem anymore, it’s time to take a comprehensive review of the problem-space and think about what has to change. This isn’t the same thing that we developers always call for: too often the refactoring is just “let’s make the code feel better”—but that’s never going to fix anything because your knowledge of the problem is always trying to catch up to the reality.
Next time you hear “let’s take a week to improve our code” or “let’s stop and get things more stable,” try taking that as a cue to review your design and workflows. Forget about the refactoring for a week or two and just focus on identifying what parts of your workflows are common and which are special cases. Once you are armed with that knowledge, you’ll be well equipped to do the right refactoring, and not before.