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