In college, I was a member of the UP Computer Society. There were a lot of geeks in our organization but its members have interests beyond computers. Every year we sponsor a quiz show called ‘TrivBits’. It is an ordinary quiz show like Battle of the Brains with a few twists:
1. Categories are selected in random
2. Questions are drawn randomly.
3. The question and eventually the answer must be projected on a wide screen.
1 and 2 are easy. For #3, the host should be able to see the answer so he could say “Correct” or “Incorrect”. But the contestants and audience should not see the answer yet otherwise it wouldn’t be quiz show and it wouldn’t be exciting for the audience. But since the questions are drawn in random and there are thousands of these, we cannot just print all questions in an index card.
Our solution is to provide two computer terminals – one for the host, one for public display of questions, and let the host control the display of the public terminal. We nicknamed the program running in the host’s terminal, “Commander”, and the other terminal “Trooper”. Questions are stored and randomly picked from an Access databases in the “Commander”. The questions and answers are then sent via serial port over the “Trooper”.
When we started, all we know was Windows 95 is cool and that we should abandon the old MS-DOS version. We were college students and we had no prior experience producing a Windows-based program much less implement a networking solution.
On the whole week we conducted the quiz show, we encountered a lot of problems but we can say it was a big step for our small organization. We had a Windows-based program when Windows 95 is just barely a year. We were able to control the behavior of another program on another PC. OK, I admit, was so geeky.
There was no doubt among us that the program should be improved. Since the next quiz show will be a year after, we have a long time to fix the code. I am contrarian and I have something different in mind. The current code is an experiment. Like any good experiment, learn from it and throw the research materials away.
I started from scratch and never looked at the old code. I even switched from Visual Basic to Delphi. And like many good procrastinating students, I started working on it only a few weeks before deadline 🙂
Not many programmers have the benefit of starting from scratch or throwing away old code. Lucky for me, I have no boss to justify what am I doing. But even then, I wonder if throwing away code should be considered bad practice.
What if you inherited a bunch of code that were maintained by more than a dozen people over the past 5 years? You could tell there were a lot of maintainers because of the different coding styles, naming convention, and program organization. Everybody in your team, even the veterans agree that the code is a mess. What should you do?
Software development starts with a lot of ideas. You have an idea on what the interface would look like, what the classes are, or what protocol you will use. OK, there is the detailed specs but until the specs is transformed into a software you could actually use, everything is just an idea.
While we write code, these ideas are validated and transformed into working software that brings millions to our company and salaries and bonuses to us programmers. Unfortunately, that only happens in the ideal world.
In the real world, you are constrained by time, cost, working condition, and by a boss who reminds you everyday that you promised the software 1 week ago. Oftentimes, we skip design, bypass testing, and leave the 100-line foo_what_ever() as is just to get the frickin’ software out before you get the 10th follow-up email from he who must not be named.
Writing version one of a software is an experiment – you experiment with the design and the implementation. The sooner you conduct your experiment and get the results, the better. What you learned from these experiments must be fed right back into your next code. This is why software gurus always tell us that writing software is a learning process. Along the way, you learn the most appropriate design, the most practical implementation, the user-friendly interface, etc.
The problem is some organizations hold in high esteem the mantra “do it right the first time.” Mistakes are not tolerated and trying things out are not allowed. Every piece of code is considered written in stone. There is no room for improving the code or making it maintainable which is ironic because 60 to 70 percent of software costs is associated with maintenance. Even then, most software groups assume that once that piece of code is committed to CVS, it should never be touched again. Even though programmers know that the code is buggy, or inefficient there is apprehension in asking for another round of time to fix the code because management views it as “should have been right the first time” and that if the code is buggy and inefficient, it is a programmer-issue, and not a management issue.
Programmers, by nature, don’t want to write buggy and inefficient code. We pride ourselves of following every advice by Steve McConnell. We want to become the Picasso or the daVinci of software. But if unrealistic schedule, vague specs, bad working condition, out-dated tools, slow computers are thrown in, then it becomes a management issue.
Similarly, some don’t see refactoring code as productive. Companies want programmers to write new code because new code means new features which means new revenue. But in reality, it hurts the organizations ability to write new code because the existing one is so fragile that if a building were created the same way, the 1st ant to jump will cause the building to come crashing down.
What people often forget is that we learn a lot more from mistakes than when we do it right. Therefore, we should always make room for experiment and mistakes, especially if people are working on new technology or product.
We should not also equate mistakes with failure. If a programmer committed a mistake in writing the authentication code, he didn’t fail. He succeeded because he now knows 1 way not write an authentication code.
A dark side of “version 1 as an experiment” is that if the code is messy, throw it away and start from scratch. If you have a product, rewriting code from scratch is always a bad idea. When I re-wrote the quiz show program, the deadline is manageable (the next quiz show is 1 year from now) and there is no boss to worry about. More importantly, this is not a commercial product where other people are relying on its delivery so they could collect their paycheck and buy milk for their kids.
Even if the software is fundamentally flawed and bug-ridden, not every line of code is a waste. It makes sense to rewrite the parts that are buggy, but it is stupid to throw away the working part just because some maverick wants to bulldoze the whole code base and rewrite it in Ruby.
Starting from scratch is not a guarantee that the new codebase is bug-free. You may not have the same developers with you and they are not guaranteed to be better than the previous developers.
There’s also the fundamental question – what makes it a mess?
“Oh, it does not use the Factory pattern and this class should have been a Singleton.” The kind of reasoning is crap.
“The code is inefficient.” What part? I’m sure it’s not the whole program. Find out the inefficient part and don’t decide to rewrite until you reviewed it. That’s the smart thing to do.
So what happened to version 2 of our quiz show program? It was better. Instead of crudely rendering lines to show a hexagon, I created a custom control (I think it was called OCX back then) that displays faster. My code is simpler thanks to the simplicity of Object Pascal. After version 2, I became inactive in our school organization and I have no idea what happened to my program. I think one freshman computer science student commented that my code was a mess and decided to rewrite it in Java.