The more I program, the more I believe this statement: you’re not just programming for today, you’re programming for today and for six months from now when you crack the code open again to make a change and think, “Now, how does this code work again?”
The fact is, things that make sense today, may not make sense that next time you look at it. Joe and I were just talking the other day about how we’ve looked through code we wrote years ago, and couldn’t believe we wrote it. We had no memory of it, and we had no idea what we were trying to do in certain places.
So, how do you protect against code rot — those things that when you look at them later, just don’t make any sense? Or those things that do make sense, but totally suck and make changing something hard?
These are going to sound condescending and pedantic, but here are a couple ideas:
Comment well. As we discussed in a post a few days ago, don’t comment everything, but comment those things that you might forget. Act like that guy from Memento, who had to leave himself little notes because he forgot everything.
Avoid hacking out crappy code. This is obvious, but how many times have we taken shortcuts because “it’s not big deal, it’s just this one little thing”? Every time I do something half-assed to save some time, I always come back to the code and regret it. I rarely ever regret taking the time to do it right.
Educate yourself on how to write code. This sounds obvious too, but how many times do you find yourself writing some convoluted code and thinking, “Man, I know there’s a better way to do this…” Find that way. If it feels wrong, it probably is wrong, and you’ll likely regret it later.
Don’t repeat yourself. If you find yourself writing the same code in two places, rarely is it a good thing.
Now, you have to balance these points again the concept of YAGNI — “You Ain’t Gonna Need It.” I just learned this acronym the other day, courtesy of Jeff Atwood’s reference to an Anders Hejlsberg interview:
If you ask beginning programmers to write a calendar control, they often think to themselves, “Oh, I’m going to write the world’s best calendar control! It’s going to be polymorphic with respect to the kind of calendar. It will have displayers, and mungers, and this, that, and the other.” They need to ship a calendar application in two months. They put all this infrastructure into place in the control, and then spend two days writing a crappy calendar application on top of it. They’ll think, “In the next version of the application, I’m going to do so much more.”
Joel Spolsky calls these people “architecture astronauts”:
When you go too far up, abstraction-wise, you run out of oxygen. Sometimes smart thinkers just don’t know when to stop, and they create these absurd, all-encompassing, high-level pictures of the universe that are all good and fine, but don’t actually mean anything at all.
And these are good points — how much crap does your app actually need?
In the end, though, I’ve tried to learn from something else Spolsky has written: “Making Wrong Code Look Wrong.” Spolsky says:
Your eyes will learn to “see” smelly code, and this will help you find obscure security bugs just through the normal process of writing code and reading code.
If you code something the right way enough times, you train yourself to get uneasy when you see it wrong. Here’s a trivial example from C# (assume you need to cast MyNumber to an integer).
This is a small thing, but it’s bad code because you have a double conversion. You’re converting your variable to a string, and then back to an int. This is better:
I’ve learned to get a little queasy in the pit of my stomach when the see the former example. Do it the right way enough times (and know why the wrong way is wrong), and you will too.
I’m off track now (and starting to sound like an arrogant ass), so I’ll just end with this —
When writing code, always ask yourself, “Am I going to understand this in a year?” Or, “Will anyone understand this but me?”
If not, figure out why. Do you need to comment? Do you need to take 30 more minutes and do it the right way? Do you need to finally figure out, once and for all, how to dynamically load a class so you can get rid of 50 lines of really stinky code?