Saturday, June 16, 2007 3:11 PM
Olaf Conijn
Paranoid Programmers
Most people should be familiar with the term “defensive programming”. It’s a way of writing code, in which the default mode is to explicitly check all assumptions you have in mind while writing logic (most of the time throwing exceptions to the caller).Though, when does this make sense?
Assume you are developing a framework, application host or plug-in to an application host. How sure are you all the assumptions you have in mind hold, once having released whatever you are working on “out in the wild”?
What if a “friendly hacker” wants to exploit some unforeseen extensibility point in your framework, making it do cool stuff beyond something you thought was possible… would that be gain or loss in value for your framework?
Think of all the mash-ups people made against google maps, flicker, whatever web 2.0 stuff is out there. Or extensions made to “application hosts” such as the Visual Studio Shell (soon to be released and positioned as a true application host!).
My default mode is different: I won’t check assumptions I have when coding, “unless …”:
- I am exposing some surface of an application to whomever (for instance a public service boundary, user input, whatever “unfriendly hackers” could exploit to do bad things).
- I am shielding from conditions that simply cannot be handled gracefully (and will throw an exception anyways). Most of which can be done through basic parameter guarding.
-Etc
When exposing a public API I’d love to have people do whatever they think makes sense.
In return, whatever I expose meets some basic assumptions, around stuff like thread-safety, security and in general its behaviour (implied through convention or somehow more explicit).
If something is not thread-safe or possibly unsecure it should not be part of the public API.
Example would be a pattern such as:
FooBar foo = bar.GetContextualSomething() as FooBar;
if (foo != null) // whatever ContextualSomething I get back, my logic only applies on a FooBar
{
foo.DoStuff();
}
I agree that having an API that works regardless of how it is called wouldn't make sense either, though the consumers of a framework know the problem they are trying to solve best. So why not give them the benefit of doubt?
Filed under: Architecture