Sunday 21 June 2015

Defending Your Honour


As much as we might want to we can't always write everything ourselves, sometimes we have to use someone else's code, an old adage quoted in many forms is
"Good developers write good code, great developers use somebody else's"
Re-using existing proven solutions to problems should always be preferred but utilising someone else's code should not be done without a healthy measure of distrust.
Never assume that everyone else has the same high standards that you do, some people "do it wrong".
Everything Is Tainted Until Proven Otherwise
When writing a class or a method all data that is passed from the rest of the code base into you should be distrusted by default and should be validated before any damage can be done.
If someone passes rubbish then they should receive an error, not just to protect your code but also to inform them that your code cannot work with what they have provided and this is what they should do to fix it.
This does mean that the APIs you write must be clear about what is acceptable and what isn't, as much as possible this should be enforced by type safety. As an example if your API accepts an integer an error shouldn't be thrown if that integer is greater than 173, as the caller how was I supposed to know that? 
This distrust should also extend to data you receive from the methods you are calling, for example a method may not state that it could return null/nil but if that would cause your code problems then this should be checked for.
Not all developers document their code well, if you cannot see the source who knows what is happening under the hood, assume the worst and protect yourself against it.
Assumption Is Mother Of All Disasters
When performing a post-mortem on a problem you will quite often here things like
"I assumed that couldn't happen"
"I assumed that method wouldn't do that" 
"I assumed no-one would do that"
If you can see a potential problem never assume anything about the likelihood of it happening, this is especially true if the resolution to that problem is straight-forward.
A good example of this is the unchecked use of size constrained variables, consider the following example in C,
void DoSomethingWithAString(char *aString) {
   char someNewString[100];
   // Do some stuff
   // Copy the result and hope we don't overflow the stack!
   strcpy(someNewString, aString);
}
The nature of this function maybe that it would be unexpected for a string longer than 100 character to be passed in, but never assume.
A better solution to this problem would be to explicitly copy only 99 characters leaving room for a null terminator. 
The only assumption you should make is that someone at sometime will do something stupid, make sure your code isn't made to misbehave because of it.
Help The Next Guy Out
Another aspect to defensive programming relates to trying to prevent accidental damage being done by the next person who touches the code.
The first defence against this is achieved by simply having a good design in the first place, well written code is designed to deal with change and as such there are less likely to be mistakes made when it needs to be updated.
But sometime subtle changes can help the next guy out, an example of this is Yoda Programming,
if (10 == x)  {
   // Do some stuff
}
This may look strange but it prevents anyone editing this line from accidentally turning equality into assignment, notice also how we are still using curly braces even though the if statement is a single line, this prevents anyone who needs to add extra lines in the future from accidentally placing them outside the if statement.
A large proportion of those annoying niggly bugs are caused by accidental mistakes when editing an existing code base, this kind of defensive programming can go a long way towards making sure that doesn't happen.
When writing a new piece of code you should see a clear boundary between the code your writing and the code written by others that you're utilising. Everything on the other side of the line should be viewed with suspicion and is guilty until proven innocent.
We should distrust black boxes, defending our codes honour against being made to look foolish because of someone else's mistakes. Just because you're paranoid doesn't mean the other guy isn't doing it wrong. 

No comments:

Post a Comment