Fowler Null Object Pattern: Why Use Inheritance?

Why Fowler PoEAA p. 498 define the null object pattern as follows (sample abbreviated, C # language, but not relevant):

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

INull used as a marker interface. I do not like this approach for three reasons:

  • Properties must be marked as virtual.
  • I can no longer close entity classes
  • At least (n + 1) new types are introduced (n null objects, one marker interface)

Why is this not implemented like this:

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

As a rule, I found all the Fowler examples well thought out, and there should obviously be something that I missed here.

+4
source share
4 answers

The reason for inheritance is to override class behavior. The way you think about it is similar to what you are going to check if the object you have has a static NullCustomer instance to make a decision, however the point of the null object must support the Liskov Substitution Principle .

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

+10
source

The problem with your second example with a magic value is that if your class has other elements that are part of the class, now you need to insert checks against magic in order to decide whether to return the information or any other relevant information.

With the Null class, the class returns what makes the most sense if such checks are not required.

For example, a customer class may return a total dollar spend by this user after polling the database as necessary. NullCustomer will simply be able to return 0; . With a magic value, he will either extract information for the dummy user from the database, or must perform another specific check before doing the reasonable thing.

+1
source

Addition to what Chap said. The Null Object pattern is used so that the default set of values ​​is valid. Also, if you try to use NullCustomer in MVC, you can still access the object representing the model, instead of considering potential non-existent data. [checking for zeros]

0
source

I'm not a C # programmer, but in your second example, it looks like you can make an equivalent:

 Customer.NullCustomer.Name = "Not Null"; 

In general, objects have behavior, not just data, so it becomes more complex.

0
source

All Articles