Reconciling the Boy Scout Rule and Opportunistic Refactoring with code reviews
- by t0x1n
I am a great believer in the Boy Scout Rule:
Always check a module in cleaner than when you checked it out." No
matter who the original author was, what if we always made some
effort, no matter how small, to improve the module. What would be the
result? I think if we all followed that simple rule, we'd see the end
of the relentless deterioration of our software systems. Instead, our
systems would gradually get better and better as they evolved. We'd
also see teams caring for the system as a whole, rather than just
individuals caring for their own small little part.
I am also a great believer in the related idea of Opportunistic Refactoring:
Although there are places for some scheduled refactoring efforts, I
prefer to encourage refactoring as an opportunistic activity, done
whenever and wherever code needs to cleaned up - by whoever.
What this means is that at any time someone sees some code that isn't
as clear as it should be, they should take the opportunity to fix it
right there and then - or at least within a few minutes
Particularly note the following excerpt from the refactoring article:
I'm wary of any development practices that cause friction for
opportunistic refactoring ... My sense is that most teams don't do
enough refactoring, so it's important to pay attention to anything
that is discouraging people from doing it. To help flush this out be
aware of any time you feel discouraged from doing a small refactoring,
one that you're sure will only take a minute or two. Any such barrier
is a smell that should prompt a conversation. So make a note of the
discouragement and bring it up with the team. At the very least it
should be discussed during your next retrospective.
Where I work, there is one development practice that causes heavy friction - Code Review (CR). Whenever I change anything that's not in the scope of my "assignment" I'm being rebuked by my reviewers that I'm making the change harder to review. This is especially true when refactoring is involved, since it makes "line by line" diff comparison difficult. This approach is the standard here, which means opportunistic refactoring is seldom done, and only "planned" refactoring (which is usually too little, too late) takes place, if at all.
I claim that the benefits are worth it, and that 3 reviewers will work a little harder (to actually understand the code before and after, rather than look at the narrow scope of which lines changed - the review itself would be better due to that alone) so that the next 100 developers reading and maintaining the code will benefit. When I present this argument my reviewers, they say they have no problem with my refactoring, as long as it's not in the same CR. However I claim this is a myth:
(1) Most of the times you only realize what and how you want to refactor when you're in the midst of your assignment. As Martin Fowler puts it:
As you add the functionality, you realize that some code you're adding
contains some duplication with some existing code, so you need to
refactor the existing code to clean things up... You may get something
working, but realize that it would be better if the interaction with
existing classes was changed. Take that opportunity to do that before
you consider yourself done.
(2) Nobody is going to look favorably at you releasing "refactoring" CRs you were not supposed to do. A CR has a certain overhead and your manager doesn't want you to "waste your time" on refactoring. When it's bundled with the change you're supposed to do, this issue is minimized.
The issue is exacerbated by Resharper, as each new file I add to the change (and I can't know in advance exactly which files would end up changed) is usually littered with errors and suggestions - most of which are spot on and totally deserve fixing.
The end result is that I see horrible code, and I just leave it there. Ironically, I feel that fixing such code not only will not improve my standings, but actually lower them and paint me as the "unfocused" guy who wastes time fixing things nobody cares about instead of doing his job. I feel bad about it because I truly despise bad code and can't stand watching it, let alone call it from my methods!
Any thoughts on how I can remedy this situation ?