Skip to content

Null Object Pattern : Design Patterns

Anand Patel edited this page Nov 28, 2016 · 12 revisions

The null object pattern is a very simple and useful pattern. When implemented properly, it can greatly reduce the amount of code by eliminating all the checks and guards against null object references. The pattern is used to shield clients from having to handle a null case when a service or an objects returns a null. This is accomplished by returning an object that is a ‘null implementation’ for the case when no result is found.

The Null Object pattern is also know as the ‘Stub’, the ‘Active Null’ pattern, or the ‘Do Nothing’ pattern.

HOW

Instead of passing null references and checking for the presence of null before any operation, you create a specific class that represents a non-functional dependency. This class implements an expected interface or inherits from an abstract class but includes no functionality. Its methods and properties perform no action and return default, fixed values. This allows any dependant object to use null object dependencies without performing any pre-checks, simplifying the code.

Real World Use Case

The null object pattern is usually used with other design patterns.

  • The null object class itself is often created as a Singleton. This limits the number of instances to one, which is ideal as null objects generally have no state and no functionality so creating additional objects would add unnecessary overhead to your software.
  • Another design pattern that is often found with the null object pattern is the strategy pattern. When one of the strategies requires no functionality, a null object can be used.
  • A third common associated pattern is the factory method pattern, where the factory may return a null object instance.

Example

BEFORE

public interface IShape
{
     void Draw();
}
public class Square : IShape
{
     public void Draw()
     {
          Console.WriteLine("Drawing a Square...");
     }
}
public class ShapeService
{
     public IShape GetShapeById(int id)
     {
            // Details of method removed for simplicity
            var square = GetShapeFromDatabase(id); 
            return square;            
     }
}
public class Program
{
     public static void Main()
     {
          var shapeService = new ShapeService();
          var shape = shapeService.GetShapeById(3);

          shape.Draw(); // Can cause a null reference exception
      }
}

//With Exception Handling
public class Program
{
     public static void Main()
     {
          var shapeService = new ShapeService();
          var shape = shapeService.GetShapeById(3);

          if (shape != null)
          {
              shape.Draw();
          }
     }
}

AFTER

public interface IShape
{
     void Draw();
}
public class Square : IShape
{
     public void Draw()
     {
          Console.WriteLine("Drawing a Square...");
     }
}
public class NullShape : IShape
{
     public void Draw()
     {
         // Do Nothing
     }
}
public class ShapeService
{
     public IShape GetShapeById(int id)
     {
          var square = GetShapeFromDatabase(id);
          return square ?? new NullShape();
     }
}
public class Program
{
     public static void Main()
     {
          var shapeService = new ShapeService();
          var shape = shapeService.GetShapeById(3);

          shape.Draw(); // No need to check for null
      }
}

Code

https://github.com/anandtpatel/CSharpCode/blob/master/src/CSharpCode/DesignPatterns/NullObject.cs

References

Clone this wiki locally