Roll Up Your Sleeves
Have you ever stared into a code mess? I don’t mean some little mess, but rather the kind of mess that, as Nietzsche put it, stares back into you if you stare at it for too long. You can almost feel it making you worse at programming. It’s the kind of thing that everyone agrees is a mess with no dissent. It’s the 10,000 line class or the class titled GlobalVariables that houses hundreds of them. It’s the kind of mess that leads to someone having you add a few more lines to that Godzilla class or a few more globals to the mix in order to get things done, and hating yourself as you do it. I think you’ve probably seen it. It’s an experience you don’t quickly forget, and one you may even commemorate with a submission to The Daily WTF.
There are a variety of ways that people respond to this state of affairs. Some will shrug and adopt a “when in Rome” attitude as they blithely break another window in this dilapidated building. Others will refuse to make things worse (at least inasmuch as the group political dynamic allows) without making things better either. Still others will apply the so-called “Boy Scout Rule” toward small, incremental improvements, fixing the application a few squashed globals and factored out methods at a time. But, there is another category of response to this, and it is the theme of my post today. That category is the rolling up of sleeves in an effort to “do this right, once and for all.”
If Some Is Good, More Is Better?
The people who take this latter approach, sticking with the Nietzsche theme, probably consider themselves uber-boy-scouts. Boy scouts aim to leave the code a little better than they find it, but uber-boy-scouts aim to leave the code a lot better. Curiously, however, boy scouts tend to get a lot done over time toward improvement, whereas uber-boy-scouts generally accomplish nothing. What gives? If some is good, isn’t more better?
Well, as it turns out, not always. Cupcakes, nighttime sleep aids, and bourbon all come to mind as counter examples of the premise, and boy-scout methodology tends to fit here as well. But, unlike the others the issue isn’t “some things are better in moderation.” There’s a subtly different issue at play here. The problem isn’t that too much fixing is bad, but rather that the fixing never actually starts happening in the first place.
And why not? Well, because of the slippery scope. The boy scout says “I’m going to eliminate these two global variables and call it a day. Maybe tomorrow, while working on my next feature, I’ll knock out three more.” The uber-boy-scout says:
While I’m doing this, I’ll knock out these two global variables. But really, if I’m going to do that, I should knock out these other ten. And, besides that, we really should break this global class up into 5 smaller globals classes, which will involve changing some namespaces around. Once we do that, we’re going to have to touch just about every class in the application. Wow, this is a huge effort. And, not to mention that the Godzilla class is using these globals and that’s part of what makes it so big, so we really also need to factor a few methods out of Godzilla into a new class in a new folder. I’d better clear my calendar this week. And, as long as we’re creating that folder, we should probably also add these other three classes, which could implement a state pattern for the GUI. And, as long as we’re doing that…
…wow, I just don’t think this refactoring is feasible right now. We’ll have to revisit this in vNext.
What makes this even worse is that, after careening down this slippery slope of needed changes, the uber-boy-scout actually tends to turn into the “when in Rome” developer, reasoning that there’s really nothing he can do right now but go along to get along. The uber-boy-scout has sort of an all-or-nothing mentality that if he can’t fix all of the broken windows in the next ten minutes, he might as well break some more so that he has an even stronger reminder to fix them all in 10 minutes at some date to be determined later.
The Fallacy Of It All
For those not familiar with rhetorical logic, slippery slope is a logical fallacy.
The Slippery Slope is a fallacy in which a person asserts that some event must inevitably follow from another without any argument for the inevitability of the event in question. In most cases, there are a series of steps or gradations between one event and the one in question and no reason is given as to why the intervening steps or gradations will simply be bypassed.
Slippery Scope, as I’m coining it, is the engagement of this fallacy in the domain of software refactorings. That is, it takes on the form “if we’re going to refactor A, we might as well/have to/should refactor B, and if we’re going to refactor B, we might as well/have to/should refactor C, etc, ad nauesum“. It is also a form of the false dilemma fallacy (e.g. “if you’re not with us you’re against us”) in that it basically asserts that either all refactorings or none must be performed.
But whatever you want to call it, the reasoning is demonstrably fallacious. And, it’s also obviously fallacious, so why do people do this? My hypothesis is that there are two main motivations for uber-boy-scouting. The first is earnest and benign — the person in question is rather excitable and thinks a mile per minute. And, once the refactoring cat is out of the bag, it’s hard to say “no, I’m not going to fix everything right now.” The uber-boy-scout has discovered a problem and can’t bear the thought of not addressing it forthwith. In situations like these, the uber-boy-scout can probably be convinced to ratchet it down to regular boy-scout.
In the other scenario, which is probably far less common, I think the motivation is laziness and mild deception (perhaps even self-deception). In this scenario, the uber-boy-scout actually prefers the status quo and its mess, but knows that he shouldn’t. So, he tosses out the refactoring idea as a false flag, chaining together all of the work that would be required to fix the mess and concluding with the flourish that it’s just not feasible, so… “when in Rome.” He gets the ‘benefit’ of continuing to play in the mess while not suffering the reputation blowback of actually liking the mess. Dealing with a passive-aggressive scheme like this is significantly trickier and group realpolitik dynamics are beyond the scope of this post.
Concentrate on Fixing Your Own Tendencies
So, rather than talk about how to fix others, I think we could all benefit from looking at ourselves and doing an honest assessment as to whether or not we exhibit uber-boy-scout tendencies. Do we fall into a nice rhythm of methodically and constantly factoring the code toward improvement, or do we tend more toward these all-or-nothing, heroic refactorings? If the answer is the latter, my advice is to reconsider your approach. Even if you pull off these refactoring coups, it’s probably at the expense of late nights, nervous team members, and a lot of stress. Be conscientious, by all means. Don’t be a “when it Rome” developer, but also bear in mind that the city in question was not built in a day.