Mark Needham

Thoughts on Software Development

Null Handling Strategies

with 6 comments

I mentioned in an earlier post my dislike of the passing of null around code, and since then there have been a couple of posts on the subject on the ThoughtWorks blogs.

I had always thought that was a silver bullet for the way that we can handle null objects in our code but it seems from reading other people’s opinions and from my own experience that this is not the case (surprise, surprise!). Several ideas of how to handle nulls came out in these posts and the comments posted on them, and it seems to me that there are several strategies for handling nulls in code.

Return null

The most common way of handling cases where there is no object to return, the code just returns null instead.

The problem with this approach is that the client now has to handle two different types of results. One if an object is returned and another if nothing is returned. This either results in code like this being scattered throughout the code base:

1
2
3
4
5
Car car = carRepository.RetrieveCar(carId)
if(car != null)
{
   car.Drive();
}

Or the client doesn’t bother to handle the null and we end up with a Null Pointer/Reference exception at some stage. Neither of these solution is particularly desirable.

Scala actually has an interesting way of getting around this problem by allowing you to define an interface which informs the client that there is the potential for nothing to be returned, therefore effectively designing a contract which allows the client to deal with it appropriately. The Option[T] idea is explained about half way down the page on this post.

This can also be done in C# to an extent by making use of the nullable operator. In C# it is only useful when you want to make it clear to the client that they may get a null value instead of a primitive.

Overall, this is the simplest solution and probably also the easiest to understand. It just doesn’t result in the cleanest code.

Throw Exception

The idea here is that if there is no object to return, the code throws a custom exception which describes the reason that no object was found.

1
2
3
4
5
6
7
8
9
public Car RetrieveCar(Guid carId)
{
   Car car = FindCarInDatabaseBy(carId);
   if(car == null)
   {
      throw new CarNotFoundException();
   }
   return car;
}

This is certainly more descriptive in telling you why nothing has been returned, but as with ‘Return null’ at some stage the alternate result from the method call needs to be handled. If this is being done with Java’s checked exceptions then it would either need to be handled by the method which calls RetrieveCar or bubbled up through the car. There are a variety of considerations for why you would would choose each way but that discussion is for another post.

As well as this, in theory you could end up with a method returning different Exceptions depending on the reason for the failure to return an object.

I’m not a big fan of handling state via exceptions as I think that exceptions should only be used where something exceptional has happened and I don’t think that failing to find an object can be considered exceptional in most cases.

Null Object Pattern

The null object pattern is the most helpful of the null handling strategies as far as the client is concerned. The client will now know that the object it has been returned is a null object, it will just see an object of the type requested. The devil is in the detail:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Car
{
   public virtual void Drive()
   {
      // Do some driving
   }

   public static Car NULL
   {
      get { return new NullCar(); }
   }

   class NullCar : Car
   {
      public override void Drive()
      {
         throw new NotImplementedException();
      }
   }
}
1
2
3
4
5
6
7
8
9
public Car RetrieveCar(Guid carId)
{
   Car car = FindCarInDatabaseBy(carId);
   if(car == null)
   {
      return Car.NULL;
   }
   return car;
}

This pattern effectively delays the need to handle the unexpected behaviour exhibited by the RetrieveCar method. Depending on the implementation of the NullCar we might decide to throw a NotImplementedException if a method on it is ever called. Or we can just override every method to do nothing which just hides the problem as far as I’m concerned.

These are the main ways I have come across for handling nulls. I’m sure there are others so if you know of any better ways please let me know.

Be Sociable, Share!

Written by Mark Needham

August 16th, 2008 at 1:03 am

Posted in Coding

Tagged with , , ,

  • http://lazyloading.blogspot.com/ The Sloth

    I would say that your gut feeling was right – NULL is a way to go except the case when you expect a colleciton – then empty collection is a right solution.
    Exception will require much more efforts to produce and handle. Also try-catch is a quite expensive operation.
    Null object is a classic case of overengineering – you wouldn’t need it unless you’re already employing few Strategy objects.
    There is cleaner Null solution (Resharper catches it perfectly :)
    Car car = carRepository.RetrieveCar(carId)
    if(car == null) return;
    car.Drive();

    All other methods will result in much more hassle.

  • http://blog.magenic.com/blogs/aarone Aaron Erickson

    The thing I dont like about solution 2 is that you are using an exception for an unexceptional condition – i.e. many people who live in places like Manhattan, or Wicker Park, dont have cars ;)

    That, and we are drilled in our heads as CompSci students that null is a possible condition of every object. That said, some spec that you can put on methods that will at least tell you if a null is possible is a good idea – at least for compile checking to assure that you handle null if that is a possible condition.

    That all said, from a design standpoint, null is a PITA. Would rather avoid it where possible – not having it makes things simpler, all things being equal.

  • http://itblog.eckenfels.net Bernd Eckenfels

    Returning null in a case where no result (excpet empty collections) can be expected is quite tollerable for me. However returning null for error cases where nobody expects null returns (for example in factoriey) is dangerous.

    I have the rule to require code to state “return null;” in the code and a comment in javadoc when it wants to signal something, and it should never return a variable which can eventually be null.

    Blogged about this in german here: http://itblog.eckenfels.net/archives/352-Null-returns-in-Java.html

  • Dave Kirby

    An alternative is to give the caller the choice.

    An example is the Python dictionary data type. This lets you access elements in two ways. Firstly you can use the [] syntax, which raises an exception if the element is not in the dictionary. Secondly you can do it via the get method which lets you specify a default value to be returned, and the default value defaults to None (the Python equivalent of null) if it is not specified.

    i.e.

    d = {} # create an empty dictionary

    d['foo'] # raises KeyError

    d.get(‘foo’) # returns None

    d.get(‘foo’, ‘something’) # returns ‘something’

  • http://whois.domaintools.com/chanslife.com/ unlIche

    Подскажите шооблончег под WordPress 2.6.2, чтобы был похож на ваш blog.kriskemper.com.

    Заранее благодарю)

  • http://chanslife.com/ Arcard

    Занимаюсь дизайном и хочу попросить автора blog.kriskemper.com отправить шаьлончик на мой мыил) Готов заплатить…