Null Object design pattern instead of returning null
This is just a quick post to make a plug for the Null Object design pattern. I don't think that it's used a lot, but it's useful to avoid a lot of issues.
It's very common to create or use methods and properties that return null. That's not surprising. It's part of most of the programming languages we use nowadays. However, returning null can lead to issues because if the callers forget to test for null, it will likely provoke a NullReferenceException (or equivalent).
What the Null Object design pattern suggests is to always return a valid instance instead of null. Where you used to return null, you would return an object with a "null" or default behavior/state.
Example:
customer = GetCustomer();
plan = (customer != null) ? customer.Plan : BillingPlan.Basic;
can be replaced with
plan = GetCustomer().Plan
if GetCustomer never returns null, but instead an instance of NullCustomer (or DefaultCustomer), which is a sub-class of the Customer class and whose Plan property is defined as follows:
override BillingPlan Plan
{
get { return BillingPlan.Basic; }
}
This is the same approach as returning an empty array instead of null. When you return null, the callers need to check for null. When you return an empty array, the callers can try to iterate it without a problem - even if they forget to check for null.
Compare the following methods for example:
Customer[] GetCustomers()
{
if (!Initialized)
return null;
... // return data
}
and
Customer[] GetCustomers()
{
if (!Initialized)
return new Customer[0];
... // return data
}
Here are two pointers to learn more about this pattern:
- http://www.refactoring.com/catalog/introduceNullObject.html or http://sourcemaking.com/refactoring/introduce-null-object
- http://cs.oberlin.edu/~jwalker/nullObjPattern/
Keep in mind that this is just a pattern, and like the other ones it's not to be used blindly in all cases. Returning null is of course perfectly fine where it makes sense.