This week I’ve been refactoring and improving some code in a .Net world. In last few weeks I also had some close encounters with Java as well. When looking at the code in both environments I realized that there is a lot of checking for null values on in a code. Where it is not a bad practice to check for null it actually presents another problem.
For someone like me when I was new to a code I couldn’t guess, what is the goal of that check. When you dealing with null the very important thing is to know where they came from and why it happened that null values occurred. When dealing with integration points it is even more important.
As you can guess code:
if (serverResponse == null) { DoSomeStuff(); }
is not very descriptive. What actually happend when I got null, does it mean that there was a communication problem, error occurred or perhaps a null means that the operation was successful.
I think the best approach will be to avoid nulls if it is possible at all. Ways we could try to avoid it:
• use Maybe pattern
• create Empty object values
• use Null Object pattern
Maybe pattern
I’m not sure if that is it’s appropriate name but I’ve used it on few projects and it seems like people are referring to it this way.
Have a Maybe interface and return it instead of the object itself.
interface Maybe<T> { bool Hasvalue; T Value; }
Also have two implementation of the interface:
public class Something<T> { private readonly T _value; public Something(T value) { _value = value; } bool HasValue { get { return true; } } T Value { get { return value; } } } public class Nothing<T> { bool HasValue { get { return false; } } T Value { get { throw new InvalidOperationException(); } } }
When returning value from an object return Maybe. Collaborator that consumes value can check if it is Something or Nothing or just ask if it has value.
Empty Object value
Just like string.Empty you can implement Empty or something similar as predefined value on your type. For example:
class Hen { Egg LayEgg() { // doing stuff return Egg.Empty; } } class Egg { public static Egg Empty = new Egg(“nothing in it”); }
You can always check before the execution if the egg is empty.
Null object pattern
Object with no default behavior. For example:
interface TV { void ShowMovie(); } class LCD : TV { void ShowMovie() { // showing movie } } class Plasma : TV { void ShowMovie() { // showing movie } } class NullTV : TV { void ShowMovie() { // do nothing } }
If something is not working well and we don’t have any of the TVs available we could return NullTV and nothing will happen.
Using the patter we can validate by type if the returned TV is a valid object and act accordingly.
I’m interested what other approaches people are heaving. Also what are the approaches in dynamic languages like Python or Ruby.
Please add your comment 😉
Greg
The Maybe pattern is part of the .Net Framework since 2.0. They’re called Nullable Types (see the C# spec – http://bit.ly/ci6lQf)
I’ve discussed similar things in the past, see Returning null considered dishonest and The curious case of the missing present.
I think that the Maybe idea is sometime applicable, although you can still end up doing a check (if (result.hasValue())) instead of (if (result == null)).
My first option (which you don’t have on your list) is to throw an exception. In practice, if I always ask a valid request, I’ll never throw. When I do throw, it’s because I ran into a problem that I hadn’t previously expected, and now I can decide which pattern best fits (if any)
I try to defer making a decision on how to deal with it until I know just how much of a problem it is 🙂
Interesting post, mainly regarding the Maybe pattern. I’ve blogged about this subject before: http://rafaelnaufal.com/blog/2006/11/15/indicating-the-absence-of-an-object/
Thanks for the comments guys. Good links, very helpfull 🙂
Would like to hear an opinion from someone on the dynamic language like Ruby or Python.
Cheers
How is
if (value != null)
different from
if (value.HasValue)
If you really like the syntax for the latter, come up with an extension method that does the same thing.
Good post! As you write, null checks are not very descriptive, if they are not argument checks.
The Nullable struct in .NET is really useful but only works with value types, since classes are nullable as they are.
One thing to keep in mind though is that Empty objects are actual values, null represents the absence of a value. String.Empty vs a null string is a good example of this.
One easy thing to do is turn those null checks into booleans first, to make it more descriptive for the next person who works with the code:
Instead of:
if (serverResponse == null)
{
// DoStuff
}
Write:
bool serverNotAvailable = (serverResponse == null);
if (serverNotAvailable)
{
// DoStuff
}
I think that null objects makes the code clean and easier to read than the other two patterns
Does it matter which one you use? In the end, what matters is that you are forced to tackle the null…
So what if my method contract instead is: I’ll return you a proper object, or throw a checked exception (heh, I guess it would only work in Java).
What you get out of that is the same as above, no problems with null. You are forced to deal with the exception, and importantly, the exception can carry much better failure information than your NullObjects or Maybe’s.
What do you think?