views:

311

answers:

4

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.

+1  A: 

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.

Alister Bulman
ok, so the problem is about methods (calculations etc. ) rather than simple get set properties.
Johannes Rudolph
+6  A: 

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).

Chap
You made a typo in Liskov's name.
Marcel Gosselin
ok, so the problem is about methods (calculations etc. ) rather than simple get set properties ? (same question to Alister)
Johannes Rudolph
Yes the behavior is in the methods and even the properties. Notice in your example the setter is missing in the null object. This changes the behavior from the base class, in which the null object is read only.
Chap
setter was ommited for shortening the code only, but you are right, null objects should be immutable anyway. I don't like properties with observable side effect anyway, but thanks for clarifying.
Johannes Rudolph
A: 

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]

monksy
A: 

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.

Tom Hawtin - tackline
yeah you got that right, others have mentioned that already though. Thanks for commenting anyway.
Johannes Rudolph