Coding DefensivelyI hate debugging. I don't know about you, but for me, coding is about the thrill of the chase - trying to find a simple, elegant way to solve a problem that everyone else thinks is impossible to solve. That's what gets me up in the morning, and why I love what I do. Debugging, on the other hand, is nothing better than mind-numbing drudgery that is unfortunately a necessary evil in order to achieve that coder's high Nevertheless, I have accumulated a few methods of decreasing the number of bugs, which, while not eliminating the dreaded root canal, does seem to lessen the duration - which is something...I guess. The primary one that I employ and that I try very hard to instill in my team is the idea of defensive coding. The idea, here is to take each piece of code you write - function, component, or custom tag - and assume that your boss will assign its implementation to either your mortal enemy or the world's largest moron - your choice. Along with this assumption, you can include the notion that your idiot boss (hey, he's the one who hired that guy. He deserves the "idiot" moniker.) is smart enough to not let him change your code, but dumb enough to assume that whoever wrote the line of code mentioned in the error message is responsible for the error. Also assume he's really anal about no errors and is capable of assaulting you with a summer sausage. Ok, enough ass-u-me-ing. The point is, if you really believed all that, you would start writing your code differently. Take the following udf for example: <cffunction name="growCarrot">
It's a fairly well thought-out and architected piece of programming, all things considered. But lets say our moron-enemy does something like this:
<cfargument name="seed"> <cfset ground.plant(seed)> <cfset sun.shine(ground)> <cfset rain()> <cfreturn ground.harvest()> </cffunction> <cfset myCarrot = growCarrot()>
That would definitely cause a problem with our code. If fact, if "ground" and "sun" aren't initialized correctly, we could be in trouble too. And while we all agree that it would be Wilbur the wonder-monkey's fault, the boss won't see it that way, and I'm in no mood for a cured-meat-sized bruise. Let's see if we can get that unnatural pork-product aimed at our co-worker instead.
<!--- OR even ---> <cfset myCarrot = growCarrot(pumpkinSeed)> <cffunction name="growCarrot" returnType="carrot"> <cfargument name="seed" type="carrotSeed" required="true"> <cfparam name="ground" default="#createObject('component', 'ground')#"> <cfparam name="sun" default="#createObject('component', 'sun)#"> <cfset ground.plant(seed)> <cfset sun.shine(ground)> <cfset rain()> <cfreturn ground.harvest()> </cffunction> There, that's much better. Now our code is rock-solid, and no matter what foolish or insidious thing our nemesis tries, our hide is safe from the dangers of emotionally-abused ground meat forced into an intestine for no apparent reason. The fact of the matter is, even if this scenario is slightly less realistic than the one you program in, if you seriously take these measures for all your code, you'll soon find that the net effect is a reduction in the amount of time you spend debugging. Even if you're a lone programmer who never, ever EVER has to integrate his code with someone else's you still run the risk of your code getting called by an idiot - you! Let's face it, we all have our moron moments, but if you make a habit of writing all your code defensively, you'll find that those moments are revealed instantly instead of laying dormant, waiting to show up and the most inopportune moment. |
There are no comments for this entry.
[Add Comment]