Scott Dorman

ephemeral segment

  Home  |   Contact  |   Syndication    |   Login
  599 Posts | 10 Stories | 848 Comments | 51 Trackbacks

News


Post Categories

Image Galleries


Microsoft Store


Creative Commons License



Locations of visitors to this page

Subscribers to this feed

TwitterCounter for @sdorman

View blog authority

Add to Technorati Favorites

Windows Live Alerts

AddThis Social Bookmark Button

LinkedIn profile

Community Credit profile

The Code Project

Follow me on Twitter

Get Free Shots from Snap.com

Community Credit Hall of Fame

Get Feedghost

Xobni outlook add-in for your inbox



Support This Site

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: ,
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
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.


# re: What is “Defensive Programming”? 4/23/2009 6:07 PM loco
Good article, exactly what do i think
People usually thinks that all input data is correct, for strange reasons

Once user starts doing some input forget about correct data.

About asserts
Yes, it is a good practice, but it works at development type only. Once you shipped an app to a customer asserts won't help.

So it is better to control 'bad cases' and log them, at least - it'll help to understand what is wrong later

Simple exception handling won't help

# re: What is “Defensive Programming”? 6/18/2010 2:20 AM gauri
defensive programming is a technique that make a program more robust means error prone to unexpected events like run time errors,...

# re: What is “Defensive Programming”? 2/16/2011 11:03 AM PeterSQ
Can I declare my bias first? I know defensive programming can be the right thing to do in many circumstances; but I believe that some defensive programming techniques store up trouble.

In my view a caught and logged exception gives most of the information needed to diagnose problems that can also be tackled by defensive programming and with less code required.

Just putting an "if" around the good path code increases the complexity in the normal case and does nothing to help diagnose when the code is not being called correctly.

So in the case of your button1_Click() handler, I would at least suggest an "else" clause logging the condition; but would prefer a run-time controllable assertion e.g. (sender is Button) - where that is clearer than the exception you would otherwise get.

To give an illustration of this problem from my own experience I have read code like:
public void setFlag(boolean flagValue) {
if (this.Instruction != null) {
if (this.Instruction.getTarget() != null) {
if (this.Instruction.getTarget(0) != null) {
if (this.Instruction.getTarget(0).getRelatedEvents()
!= null) {
Event[] relatedEvents =
this.Instruction.getTarget(0).getRelatedEvents();
if (relatedEvents != null) {
if (relatedEvents[0] != null) {
Condition[] Conditions =
((Instruction) (relatedEvents[0]))
.getHasInstructionConditions();
if (Conditions != null) {
setFlag(flagValue,
Conditions);
}
}
}
}
}
}
}
}

Who would know if the flag did not get set? There should at least be a log if it is not, as the class's internal state was not appropriate for this call.

Which of these guard checks reflect meaningful states of the class and which are caused by a mindset of "there must be no exceptions from my code"?

Thanks for getting the conversation going.

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: