One major saying coming from the ancient city of Delphi is the above saying, “Nothing to Excess”. Another is “Know Thyself”, but I digress. I thought about this as I was reading, or in one case re-reading, two blog posts recently. The first is Dan North’s blog on the Software Craftsmanship movement at http://dannorth.net/2011/01/11/programming-is-not-a-craft/ and the second is by Gojko Adzic at http://gojko.net/2011/04/05/how-is-it-even-possible-code-to-be-this-bad/ on what the existence of really bad code in a really valuable and heavily used open source project says about the foundation of the software craftsmanship movement.
So where does “Nothing to Excess” fit in with software craftsmanship? I think each of these two posts describes turning a knob too far one way. Dan’s post argues that it isn’t the software that matters so much; we should care about the value delivered to the business instead. I buy this argument to a significant degree. However, as professionals, we also have a duty to our clients, “the business”, to make sure they understand the true costs associated with that value, now and later. Unless a business can simply throw things away and start over every time they need to change things, the costs associated with bad code need to be visible. Hitting a date may give significant short-term gains. However, those gains can be gobbled up if the debt incurred in the code to make the date results in missing the next one. We need to consider the life-cycle cost of the software we write, taking into account the short-term value that the business can derive and the long-term costs of maintaining that code.
I often get asked how to think about remediating an ugly code base. I suggest to people (and I am certainly not alone in this) to consider 1) how often that part of the code tends to change, using check-in logs if they exist, 2) if that code is needed to support known significant upcoming business initiatives, in case it will become important but it’s been stable for a while, 3) the extent to which changing the code results in problems, through looking again at check-ins but also at defects, and the look of sheer terror on the faces of the QA, operations and dev folks every time someone suggests changing that area of the code, and 4) the quality metrics for that piece of code. Yes, that means I advocate leaving some smelly stinking pile of code alone, at least for a long while, unless something tells me I am going to change it or the risk of touching it is incredibly high – and I would still prioritize the first two indicators.
Gojko’s post illustrates this point from a different direction. Users of the code don’t care about how good it is if they derive value from it. They start to care if poor quality makes the product unstable, affecting their ability to derive value now. They also start to care if poor code quality makes the product so difficult to change that it affects their ability to continue to derive value in the future. The comments to this post, at least when I read it, indicate some concern that this open source project is getting close to this second point. However, the users won’t care until they continue to clamor for updates that don’t arrive. Once that happens, the code quality does matter. It also matters at this stage because they now have to pay to fix the code, not necessarily directly, but indirectly through the increased cost and time to get new features out. From a business context, the business has a debt that it may or may not have made a conscious decision to take on. It is the responsibility of the development team to make sure the business understands if they are compromising the long-term costs and value of the code by taking a particular decision in the short term.
The agile social contract between the customer of a software delivery team and the team itself establishes the right of the customer to decide what he wants, which parts are more important, and how much he wants to pay overall, while the team has the right to say how much each piece costs in terms of time and effort. The customer can’t say “I want to pay 10 jellybeans and have all this by Tuesday”. The customer can say “I want to pay 10 jellybeans and I want something on Tuesday” to which the team can reply, “On Tuesday for 10 jellybeans you can get X or Y or A+B, which do you want?” This contract has another axis to be considered, though, and that is the level of quality, both internal (software) and external (functional and technical). I believe the business has every right to say, “don’t bother completely testing this – I need it out now”. I also believe that the team should make sure they understand the risks and the costs of potential failures. Unfortunately this situation can turn into an “I told you so” moment, making things tough on the development team.
It is much the same with internal quality. The business has the same right to say, “I don’t need quality work here, I need fast work”. What does need to happen, however, is for the business to remember they agreed to the cost of rework when they pushed the team to deliver more quickly than the team felt was sensible. There’s still no free lunch. Unfortunately, in my experience, things also tend to break down at this stage, but the theory is nice.
In the end, there can be a thing as too much focus on quality. Some will argue that, given the state of affairs in our industry, we should push the pendulum way over the other way first. I’d like to think there’s an easier way to find the middle ground. That middle ground clearly exists. Hopefully it isn’t too hidden in the weeds.