My fellow Elegant Coder Jan Van Ryswyck wrote about Craftmanship Over Crap. I generally agree with his point of view. Writing good, clean code is tremendously important for the long term survival chances of any software project. But i also believe that we sometimes need to be a bit more pragmatic about how we solve a problem.
A software developer’s primary goal should be to create value for the users of a system. Value can mean a lot of things here. First and foremost, it should be about things that users actually experience. Features, ease of use, performance, etc. You can get all of those with crappy code, but that leads to a situation where you won’t be able to sustain that value in the long term. A system can be very useful to its users, but if the code is in such bad shape that it can’t easily be maintained and extended with new features over time, the value of the system will slowly reduce. New features will introduce new bugs. Bug fixes will introduce new bugs. Eventually, the system starts to collapse under its own rot and the dreaded rewrite commences. Nobody really wants this, do they? If you write good, clean code from the beginning, you can usually avoid these problems.
A lot of opinionated developers claim that a true craftsman developer will never write a piece of bad code. In an ideal world, i would agree. These same developers also look down on people who implement a quick fix instead of looking for the proper solution. Again, in an ideal world i would agree with that. In the real world however, i’m not so sure if that’s always the best thing to do.
Those of you who’ve been reading my posts for a while know how important clean code is to me. I generally hate crappy code and i generally hate quick fixes that don’t fix the real problem. Then again, i do realize that we sometimes need to put our principles aside in order to be able to deliver value to our users.
Allow me to use an example to defend my position on this. I recently had to fix a nasty bug in NHibernate. Once i found the true reason for the bug’s existence i had two options to fix it. The correct solution would have required me to modify some crucial parts in NHibernate. The easiest fix required me to modify one non-essential class in a manner that couldn’t impact anything else.
Certainly, a true craftsman would go for the best solution, right? Well, let me tell you something about the NHibernate code base… it’s pretty big, it’s quite complex, and it’s been worked on by a lot of people over the years. There are parts of the code where you really don’t feel comfortable making drastic changes. Sure, we have our test-suite, but it unfortunately doesn’t cover every possible thing that could go wrong.
I chose to implement the easier fix. The bug was fixed, which means that the fix created value for everyone who’s using the trunk (which is more people than you’d think) and it means that this bug (which was a show-stopper IMO) won’t delay our 2.1 release. The correct fix would’ve meant making a risky change at this point, which could’ve led to more bugs that we don’t have tests for yet. The correct fix will be implemented right after the 2.1 release, when we have more room to make drastic changes to core parts of the code.
Was i wrong to implement the easier fix? I don’t think so… although i’m still not happy about that fix. But we have a responsibility to release software. If we would always stick to our principles, that could sometimes lead to having to delay or postpone a release. While there are many valid reasons for delaying or postponing a release, i don’t think merely sticking to your principles about a piece of code is always the best thing to do.
Of course, you do have to have the discipline to pay back the technical debt you’ve incurred when you do this, but sometimes the cost of that technical debt is less than that of having users losing faith in your product. And that, in general, is something we as software developers need to keep in mind as well. Writing good, clean code is great. We should all strive to do that. But we first and foremost need to create value for our users.