Fowler Null Object Pattern: Why use inheritance?

2.1k views Asked by At

Why does Fowler PoEAA p. 498 define the null-object pattern in the following way (sample shortened, language is c# but doesn't matter):

public class Customer
{
  public virtual string Name {get; set;}
}

public class NullCustomer : Customer, INull
{
  public override Name 
  {
     get { return "ImTheNull";}
     // setter ommitted
  }
}

INull is used as a marker interface. I don't really like this approach for three reasons:

  1. Properties need to be marked virtual
  2. I can't seal my entity classes anymore
  3. At least (n+1) new types are introduced (n null objects, one marker interface)

Why isn't it implemented like this:

public class Customer
{
  public static readonly Customer NullCustomer = new Customer(){Name = "ImtTheNullCustomer";}

  public string Name {get; set;}
}

I have generally found all of Fowlers examples well thought and there clearly must be something I have missed here.

4

There are 4 answers

4
Chap On BEST ANSWER

The reason for the inheritance is to override the behavior of the class. The way you are thinking about it seems to me like you are going to check if the object you have is equal to the NullCustomer static instance to make a decision, however the point of the null object is to uphold the Liskov's substitution principle.

In other words, you use the null object to set a reference and you will not have a special check for it, you will just use it and it should have a different behavior (really a lack of behavior).

1
Tom Hawtin - tackline On

I'm not a C# programmer, but it looks like in your second example that you could do the equivalent of:

Customer.NullCustomer.Name = "Not Null";

In general, objects have behaviour, not just data, so it becomes more complicated.

2
Alister Bulman On

The problem with your second example, with a magic value, is that if your class has other items that are part of the class, you now have to insert checks against the magic to decide to return information, or some other appropriate information.

With a Null class, the class returns what makes most sense without such checks being required.

For example, the customer class might return the total dollar spend by that user, after interrogating the DB as appropriate. A NullCustomer would just be able to return 0;. With the magic value, it would either fetch information for a dummy user from the DB, or have to run another specific check before doing the sensible thing.

0
monksy On

Adding to what Chap said. The Null Object pattern is used so that there is a default set of values that is acceptable. Additionally, if you attempted to use a NullCustomer within a MVC, you would still be able to access the object representing the model, rather than have to account for potential non-existant data. [checking for nulls]