Null Pattern is probably one of the most underestimated and often most ignored among the design Patterns., though it turns out to be one of the easiest to implement. The intend of the pattern is to ensure we won’t end up with NullReference Exceptions, while avoiding the long list of repeated preconditions that checks of null values. Instead, we provide identify and define the behavior when null object is encountered , encapsulate it in a object, and use it as you would normally use any other valid instance of the object.
Consider the following code.
public class Person :IPerson { public long ID {get;set;} public List GetEmployementHistory() { // Do some operations from Db } } // Client Code void Main() { var Employee = EmployeeCollection.GetEmployee(); var details = Employee.GetEmployementHistory(); }
The above code would throw an exception if the Employee Parameter is null. The obvious solution would be to use preconditions to ensure we handle null values in appropriate manner. We would have to rewrite the code as follows.
void Main() { var Employee = EmployeeCollection.GetEmployee(); if(Employee == null) { // Do appropriate action } var details = Employee.GetEmployementHistory (); }
However, this approach would mean that the client that invoke the GetDetails method needs to be ensure the object isn’t null. This is an unnecessary burden on the client, and on a longer run, and the chances of a client forgetting to validate the object is higher.
Null Object Pattern
As mentioned earlier, the Null Object Pattern aims to provide a default behavior ( or no behavior at all) when a null instance is encountered by encapsulating the behavior within an instance. We would do so by providing special implementation of the type, which encapsulate the behavior associated with null object.
For example, for the above code, the null object pattern could be defined as
public class NullPerson: IPerson { public long ID {get;set;} = -1; public List GetEmployementHistory() { return new List(); } }
Now we could rewrite the Client Code sans any preconditions without worrying about the null exceptions. However, here is a word of caution. We shouldn’t use the Null Object Pattern to swallow the exception unless that’s a behavior we really want. Another scenario one needs to avoid while using the Null Object Pattern is the usage of “IsNull” Properties/Method. At times , we do come across Null Object Implementation that includes a property/method which states where the object is null. For example, consider the following code.
public class NullPerson: IPerson { public bool IsNull {get;set;} => false; public long ID {get;set;} = -1; public List GetEmployementHistory() { return new List(); } }
This is NOT Null Object Pattern as it defeats the purpose of the pattern.It causes the logic to be spilled outside the object.
Sample code for Null Object Pattern can be found in my GitHub
One thought on “Design Patterns : Null Object Pattern”