Scott Dorman

blog

  Home  |   Contact  |   Syndication    |   Login
  525 Posts | 9 Stories | 466 Comments | 55 Trackbacks

News


Post Categories

Image Galleries



Creative Commons License


Microsoft MVP


MCP Profile


Subscribers to this feed

TwitterCounter for @sdorman

Locations of visitors to this page

View blog authority

Add to Technorati Favorites

Windows Live Alerts

Support This Site

IM me

Scott [MVP]

Get Free Shots from Snap.com

Community Credit Hall of Fame

Get Feedghost

AddThis Social Bookmark Button

Xobni outlook add-in for your inbox

TechEd Bloggers

Party with Palermo

PDC 2008

Windows Live Translator

Twitter












Tag Cloud


Article Categories

Archives

Post Categories

Image Galleries

My post on the Null Object pattern has generated some interesting dialog. One of the trends that I have seen is the idea that defensive programming means your code should fail as early as possible. I couldn’t agree less.

According to Wikipedia,

Defensive programming is a form of defensive design intended to ensure the continuing function of a piece of software in spite of unforeseeable usage of said software. The idea can be viewed as reducing or eliminating the prospect of Murphy's Law having effect. Defensive programming techniques are used especially when a piece of software could be misused mischievously or inadvertently to catastrophic effect.

While this is a good definition, I think it still leaves much to be desired. The Wikipedia entry goes on to say that defensive programming is one approach to improving software quality by “Making the software behave in a predictable manner despite unexpected input or user actions.”

I think this is the closest definition that actually conveys what defensive programming is all about. The idea behind defensive programming is that the application should behave in a consistent and predictable manner even in the case of unexpected conditions.

There are a lot of different ways to achieve this and they are all different depending on what you are trying to accomplish with the code, the programming language, and the control structures being used. For example, considering a switch statement:

switch (Orientation)
{
   case Orientation.Horizontal:
      break;

   case Orientation.Vertical:
      break;
}

This is perfectly acceptable code, right? Remembering that enumerations are simply numeric (generally integer) values, it is entirely possible for this switch to get passed a numeric value that doesn’t correspond to either Horizontal or Vertical. In that case, there is the possibility of the switch, or code following the switch, to crash. One option to handle this would be to add a default case to the switch:

switch (Orientation)
{
    case Orientation.Horizontal:
        break;

    case Orientation.Vertical:
        break;

    default:
        break;
}

In the default case you could throw an exception (if that’s the appropriate behavior) or, more likely, you take some action that ensures either the remaining code doesn’t execute or at least doesn’t crash.

Looking at another example, this time casting, shows some other ways to program defensively. A common scenario for casting is in UI programming and handling events.

private void button1_Click(object sender, EventArgs e)
{
    ((Button)sender).Text = "You pressed a button";
}

Again, this code looks perfectly reasonable and will work just fine until someone accidentally assigns this event handler to something other than a button. Once that happens, the code will crash since sender won’t be castable to a Button. There are several different ways to handle this but the simplest (at least in my opinion) is

private void button1_Click(object sender, EventArgs e)
{
    Button button = sender as Button;
    if (button != null)
    {
        button.Text = "You pressed a button";
    }
}

Yes, it is a bit more code but it also guarantees that no matter what happens if the object that raised the event is not a Button, the code won’t crash. You could have chosen to throw an exception (or just let the exception generated by the runtime bubble up the call stack until it’s handled, but that may not be desirable depending on what you are doing.

The bottom line is that catching exceptions (not throwing them, but catching them…and all exceptions will eventually be caught, but possibly not in a way you intended) is expensive and if there are techniques that allow your program to continue functioning properly or otherwise gracefully handle exceptional conditions, known as “defensive programming”, you should opt for that approach.

Technorati Tags: ,
posted on Friday, July 04, 2008 9:26 AM

Feedback

# re: What is “Defensive Programming”? 7/5/2008 2:04 PM Anthony Trudeau
I hope you don't think I'm beating up on you. I think your posts were an interesting start for a dialog.

I think you're moving the focus on the user input intended to developer written code and thereby taking away the focus from appropriate unit testing and rules enforcement. Your enumeration check can be done by using Enum.IsDefined on the function argument. And why would user input impact the creation of an event handler for a control? There may be some reason, but I don't see it. You as the developer should know the possible sources of your events and anything unexpected should fail.

# re: What is “Defensive Programming”? 7/5/2008 2:09 PM Anthony Trudeau
Also, I don't profess to know about the Defensive Programming methodology, but I have to disagree with it if one of its tenets is to avoid exceptions. Exceptions are an integral part of development as long as they aren't misused.

# re: What is “Defensive Programming”? 7/6/2008 10:25 AM Scott
Anthony, I don't think you're beating up on me at all. The best part of a blog is when it promotes a dialog on a subject.

The idea of defensive programming is not to avoid exceptions, but rather avoid unnecessary exceptions. Exceptions are an important and integral part of development, but that doesn't mean they are appropriate in all circumstances.

Defensive programming should in no way take away from or replace unit testing. Rather, it presents a way to help avoid common mistakes such as "blind casting". As a developer, you don't always know the possible uses of any code, particularly if you're developing public APIs.

# re: What is “Defensive Programming”? 7/9/2008 3:37 PM Sidar Ok
Hi Scott - excellent touch.

One of the main things that I strongly agree in your article is if needed, throw as early as possible - so this comes with the price of explicitly defining your assumptions.

e.g, what I would do in that event is - it is clear that we are assuming that the sender and event args can not be null, so I would put these assumptions with statements like

Debug.Assert(sender != null);
Debug.Assert(e != null);

Othewise, one should be very careful that instead of defensive programming, it can turn out to be hiding bugs that shouldnt be hidden. For instance, if button in your example is null, than that's a red alarm - it should be thrown, or at least logged somewhere.

Hope this makes sense.


Post Feedback

Title:
Name:
Email: (never displayed)
Url:
Comments: 
Please add 4 and 1 and type the answer here: