When Sun released Java 1.5 (or Java 5, as they rebranded it) many people were eager to upgrade their projects to use this latest and greatest version. And why not, it offered some compelling features (arguably), the most visible of which was generics support. The project I was working on was no exception. Of course, in the enterprise world this upgrade path took a while (as enterprise things are wont to do :)), but eventually all obstacles were removed and the upgrade happened. But, along with all the “goodness”, came the several thousand warnings telling you exactly how generics non-compliant your code was. There is nothing inherently wrong with this; it is good to know when there are issues with your code, even if these issues are relatively minor. The problem was that these warnings became a permanent fixture. You see, we do software development the efficient way these days, we prioritize everything and fixing trivial warnings, that don’t actually affect the functionality, never had a chance of being prioritized anywhere except the bottom.
Initially I had no problem with this, I am as efficient as the next guy, and I believe in prioritization, but after a while something just started to bug me about the code (no pun intended :)). It just didn’t look clean somehow and no amount of refactoring seemed to help. Plus, we just didn’t seem to be as thorough – or maybe it was all my imagination. An insight into this issue didn’t hit me until long after I was no longer on that project. You see it was all about those generics warnings! By upgrading and introducing several thousand new warnings into the code we turned our code into the ultimate house with broken windows (or at least cracked ones). And due to our well intentioned prioritization efforts, we never really had any intention of fixing this issue. You can probably guess how the story goes from here. Soon, a couple of legitimate warnings crept into the list, and before we knew it the couple turned into ten which quickly turned into several dozen. And you do try to fix the legitimate ones, but the psychological effect of staring into several thousand warnings will not be denied. Eventually you develop warning blindness (_similar to ad blindness_) and it doesn’t matter if the warnings are legitimate or frivolous, you no longer bother, you just treat them as noise.
Prioritization And Timeboxing
Prioritization seems like one of those practices that brings nothing but good. It’s pretty exciting because it is so easy to do and it has immediate benefits (_kinda like standup meetings_). We just move our features/tasks around, chop the least important ones off the bottom and all of a sudden we’re making our deadlines, we’re delivery focused. But, no practice is applicable universally. I am not trying to say that prioritization is bad; it is often a valuable and helpful practice as long as we don’t apply it blindly. There will be situations where it will make sense to prioritize a less important task/feature higher, for reasons other than its relative business value. Like the thousand warnings problem. Even a minor daily/weekly effort to fix the issue would have kept it at the forefront and prevented a tiny problem from escalating in unexpected ways.
Maybe letting a few warnings slide is not such a big deal but the underlying issue of universally applying a seemingly benign practice can manifest itself in a more insidious fashion. Let’s consider timeboxing, another one of those practices that brings nothing but good. If we timebox, we’re forced to come to some sort of decision and we don’t waste time in endless meetings and committees. Team retrospectives are a good example. During a standard retrospective every member of the team lists the issues that they consider important, the team then votes on all the issues to make sure the more important ones are discussed first (another example of prioritization). Why do we need to vote? Because, the retrospective is timeboxed, we only have X minutes and we’ll only be able to get through so many things. The problem here, is that often the same issues crop up every time, but are never voted up to the top and so are never discussed. Does that mean the problem is less pressing – possibly? Does it mean the problem doesn’t exist – not by a long shot?
If nothing gets done about an issue for long enough, people stop bringing it up. Why bother, it never gets discussed anyway, it’s more efficient to just drop it. Now you have a problem in stealth mode that can grow and develop in all sorts of unexpected ways. Such as becoming an ingrained part of the culture (_I’ve looked at aspects of culture before, it is an extremely diverse topic and I am planning to touch on it in several upcoming posts_). People get used to it, and it takes on an element of tradition. Have you ever tried to change a tradition? It doesn’t matter if it’s helpful or detrimental, once the team has fully internalized it – good luck trying to budge it. And all this as a result of timeboxing and prioritization applied blindly – practices that are benign and helpful most of the time – causing a lot of harm.
You always need to adapt and adjust according to the situation; this is why we have people running projects and not machines. If a discussion seems to be leading somewhere good, don’t worry about the timeboxing let it run, only cut it short if it stagnates. Retrospectives are the same, I do believe it is well worth spending as much time as necessary to go through all the problems the team is facing. It is a small price to pay for not allowing issues to fester. Keep an eye on what is bugging your team about the code. Prioritizing an unimportant feature higher can often deal with these issues cleanly and efficiently. It is not all about the business value, or rather, there is more to business value than just financial impact. The general health of the development team has intrinsic business value all of its own.
Images by Michael Valiant and hockadilly