Andrew Hunt and Venkat Subramaniam use the Turkish proverb, “No matter how far you’ve gone down the wrong road you’ve gone, turn back.”, rather elegantly in their book “Practices of an Agile Developer”. They comment:
"That Turkish proverb above is both simple and obvious—you’d think it would be a guiding force for software development. But all too often, developers (including your humble authors) continue down the wrong road in the misguided hope that it will be OK somehow. Maybe it’s close enough. Maybe this isn’t really as wrong a road as it feels. We might even get away with it now and then, if creating software were a linear, deterministic process—like the proverbial road. But it’s not."
Software development is about making choices. Starting from selecting the underlying frameworks your code will run on, tools you will use, a host of other choices and above all, the assumptions your code will make.
We make choices at every step. While we try our best to make our choices based on objective and pragmatic thinking, the fact is that our choices are based on the facts and requirements available at any given time. And of-course, in a real world, these change. Very often. Then, there is the pressure to ship and every developer needs to compromise some level of perfection for the sake of shipping!
Making just a couple of wrong choices can put you on the wrong way. You can try your best to avoid getting on the wrong way. I wish you luck. But the truth is, no matter how hard you try, you will take a couple of wrong turns once in a while. Building software is like driving on a confusing mesh of freeways, with an outdated map, that changes every five minutes, and having only a very general idea of where you want to get to. At some point or the other, chances are that you will take a couple of wrong exits and will get lost.
In a recent mail trail team members of a project and me discussed fixing 3 bugs in first few iterations of module. The module, which was a very small module of a large web based product, consisted of just 3 aspx pages. While these discussions were continuing, I received an email from a person who was assigned the responsibility of fixing these 3 bugs. He had completed his initial analysis on what it would take to fix those 3 bugs and this email contained his suggestion on how these bugs can be fixed. The email contained just a single line of text – “I think the code needs to be re-written.”
I consider emails of this sort particularly helpful. They tell me that we’re failing fast (And for those who didn’t click that link, that’s a good thing :)). Emails of this sort, tell me that even before we go to Testing, members in the team have actually figured out that we’ve just taken a wrong way and have raised the “wrong way” sign:
That just makes turning back very easy.
In this particular case, after a quick follow-up meeting on the mail-trail everyone agreed that we needed to fix a couple of bugs on a page, refactor a page ruthlessly and rewrite just one page because re-writing it would be faster than fixing it and would make things much better.
While spending hours and hours in trying to put band-aids on code that doesn’t work, or is badly designed, at rare occasions it’s a good idea to start fresh. In other words, “turn back”.
While turning back, works on micro-level modules, classes, small functions or code snippets, at a macro-level / project-level, more often than not, turning back is not a viable option.
At a product / project level, Joel Spolsky feels this is one of those “Things you should never do”. He explains:
"We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by incremental renovation: tinkering, improving, planting flower beds.
There's a subtle reason that programmers always want to throw away the code and start over. The reason is that they think the old code is a mess. And here is the interesting observation: they are probably wrong. The reason that they think the old code is a mess is because of a cardinal, fundamental law of programming:
It's harder to read code than to write it"
He goes ahead to explain why taking a huge project and attempting to rewrite it from scratch is not such a great idea:
"The idea that new code is better than old is patently absurd. Old code has been used. It has been tested. Lots of bugs have been found, and they've been fixed. There's nothing wrong with it. It doesn't acquire bugs just by sitting around on your hard drive."
But then, how do you turn back, especially if you have made too many bad choices and your project is a huge one? A Wise comment on this forum explains how:
"Get together a refactoring plan. This shows how you can go from a mess to something useable in incremental steps.
I've never seen a project where absolutely every single line of code was a waste. Even if the architecture underneath is flawed, the UI might be okay. So keep the UI and refactor what goes on underneath.
It's always going to be quicker than a rewrite."
Pick and choose what you need to throw away, when you need to throw it away and how much of it do you really need to throw away. While you do that, don’t forget to keep the risks-of-throwing-away-code to a minimum. When you can throw away small snippets and fix things by rigorous yet phased Refactoring, don’t attempt a monolithic rewrite by throwing away all your code.
Where am I trying to get with this? If you haven’t already noticed, I’m just trying to refactor the proverb I started off with. So, here’s my refactored version:
“No Matter how far down the wrong road you’ve gone, find the shortest, safest and smartest way to the right road.” - If writing code is an art, throwing it away is an art too!