· coding

Coding: Maybe vs Null Object patterns

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.

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket