Mark Needham

Thoughts on Software Development

Coding: Maybe vs Null Object patterns

with 13 comments

On the project I’m currently working on my colleague Christian Blunden has introduced a version of the Maybe type into the code base, a concept that originally derives from the world of functional programming.

The code looks a bit like this:

public interface Maybe<T>
{
	bool HasValue();
	T Value();
}
public class Some<T> : Maybe<T>
{
	private readonly T t;
 
	public Some(T t)
	{
		this.t = t;
	}
 
	public bool HasValue()
	{	
		return true;
	}
 
	public T Value()
	{		
		return t;
	}	
}
public class None<T> : Maybe<T>
{
	public bool HasValue()
	{	
		return false;
	}
 
	public T Value()
	{		
		throw new NotImplementedException();
	}	
}

We would then use it in the code like this:

public FooRepository
{
	public Maybe<Foo> Find(int fooId)
	{
		var foo = LookUpFooFromDatabase();
 
		if(foo == null)
		{
			return new None<Foo>();
		}
		return new Some<Foo>(foo);
	}
var maybeFoo = fooRepository.Find(1);
 
if(maybeFoo.HasValue())
{
	// do something with it
}
// fail in misery

The benefit we get from using this pattern is that we’re explicitly defining in the contract of ‘FooRepository.Find’ that the method might not return a ‘Foo’ rather than leaving the callee to work out whether or not they need to check for a null value.

It’s effectively the Nullable pattern except we can use it for reference types and not just primitives.

An alternative approach which Dermot pointed out is the null object pattern.

Typically when using that pattern we would treat the result of calling ‘FooRepository.Find’ the same regardless of whether we get a real ‘Foo’ or not.

That pattern would work quite well if we have to show a list of items in a grid, for example, and just showed blank cells if there isn’t a real ‘Foo’.

In our case we want to distinguish between whether we did or did not find a ‘Foo’ because the application behaves differently if we can’t find one. Therefore in this case the null object pattern doesn’t work so well.

Written by Mark Needham

April 10th, 2010 at 11:21 am

Posted in Coding

Tagged with

  • http://zdsbs.blogspot.com Zach

    I certainly like like returning a Maybe object better than returning a null object but what I don’t like about this is you’re duplicating the logic (I dive into an example of this on my blog http://zdsbs.blogspot.com/2009/08/returning-null.html). Your repository code + your client code each need to have that if test.

    You can remove that if and have a harder contract by changing the signature of Foo Find(int id) to void Find(FooReader fooReader) where fooReader is an interface that has:

    fooReader.accept(foo) + fooReader.noFooFound(int fooId)

    I’ve found moving toward more tell don’t ask to be very useful in situations like this.

    What do you think?

  • http://www.markhneedham.com Mark Needham

    That’s pretty cool actually. We could even not bother having the interface and do it with functions instead.

    Which would lead to something like this:
    http://gist.github.com/362051

  • http://deadmp3.blogspot.com dm3
  • http://zdsbs.blogspot.com Zach

    Oh Yeah that looks really nice. I like passing the two functions along as independent pieces and it makes the repository method signature very clear. Actions are yet another example of how Java is feeling more and more antiquated.

  • http://www.magpiebrain.com/ Sam Newman

    Scala has Option, which is somewhat similar – I think I prefer the name Maybe, rather than Scala’s Option resulting in Some or None. One question for all you Functional programmer types – Is Maybe/Option a Monad?

  • http://blogs.ugidotnet.org/luKa/ Luca Minudel

    Null Object pattern is a special case of the … Special Case pattern.

    it’s scope is to avoid the needs to write an if instruction to deal with a special case or a special value like null.

    since the code posted has 2 if, looks like the intent of the original pattern was lost

  • http://blog.gigoo.org Greg Gigon

    Hi Mark
    It appears that we are working with the same people :)
    http://blog.gigoo.org/2010/03/18/how-to-deal-with-nulls/
    Greg

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #577

  • http://www.markhneedham.com Mark Needham

    @Greg – ah cool I hadn’t seen your post, good stuff. The Ben Butler Cole influence is everywhere!

  • http://www.markhneedham.com Mark Needham

    @Sam – yeah I think it would be referred to as a Monad – presumably because (although not in this case) it should be possible to chain together a sequence of different maybes.

    The Haskell reference page describes it better than me:

    “The Maybe monad embodies the strategy of combining a chain of computations that may each return Nothing by ending the chain early if any step produces Nothing as output. It is useful when a computation entails a sequence of steps that depend on one another, and in which some steps may fail to return a value.”

  • http://www.magpiebrain.com/ Sam Newman

    That matches my understanding. Scala options could be chained together too, although I hate to imagine what the type declaration would look like :-)

  • http://bayger.pl Patryk Bajer

    Hi Mark!
    Very interesting idea, that Maybe. :) Anyway, how about a little improvement (just came to my mind)?

    http://pastebin.com/P6WNZiX5

    You could get rid of that “if” when returning Maybe value and simply write:

    return foo.AsMaybe();

    Of course it will pollute “object” class with that extension method, but maybe ;) it is worth doing that.

    Patryk

  • http://www.markhneedham.com Mark Needham

    @Patryk – yes! Actually we created that extension method just after I wrote this post :-) I’m still not sure how far to go with extension methods on object but in this case it seems reasonable.