I remember stepping into a heated discussion with two developers who just couldn’t agree whether or not they should be writing their code defensively. One of them argued they should always be checking for null, checking for illegal input and throw appropriate exceptions before doing anything with it. The other argued that they should not because of the amount of code that would add to every single method. I think I understood where they were both coming from and suggested that they were both correct though under different circumstances. One of them asked me to explain, and considering I see this argument resurfacing again here and here, I thought I’d post my thoughts.
Scenario A: Dealing with those outside of your circle of trust
Let’s say you’re working in Team A, developing an API for the greater public. It might be as big as a core platform development API, or an opensource library. Either way, it’s not possible to learn how everyone is going to use your API and not enough to simply document it because some people will not read all the documentation. Programming defensively helps consumers understand how your code was meant to called because there is no single way you can ensure your clients have the same understanding, regardless of the amount of documentation you put together. They lie outside of your sphere of influence. The longer the release cycles, the greater the risk someone might use your API in a way you hadn’t intended. This is the situation the authors of the .Net Framework Guideline worked under and as such you’ll see they’re emphasis on defensive programming. You don’t always have to do it in this situation, you’re just more likely to.
Scenario B: Dealing with those inside your sphere of influence
You might be working closely with another team, either in your organisation or in another one, writing an API for them to consume. Do you write your code defensively? I think it depends on how much influence you have. If you have enough influence that both parties understand the contract well, and your release cycles are reasonably fast, you may not have to. If you have long release cycles, or your relationship with the other team is more like the general public (you have no idea how they’re going to use your API), you may choose to program more defensively to provide faster feedback for your clients. I try to use this as the last resort when I’m in this particular situation.
Scenario C: Inside your own team
I rarely find good reasons to program defensively for code that I will ultimately write. It doesn’t really make sense for me to add in additional lines of code where I can easily test all the execution paths of the final code.
This advice is in constant practice. Even when you’re working under Scenario A, it’s only your external APIs that you are probably interested in programming defensively. Delegating to all other private or internal members will often be in the context of Scenario B or Scenario C. Remember the rule that ‘Context is King’, so ensure everyone understands that context before jumping to a particular conclusion about what you should or should not be programming defensively.