September 21, 2007
@ 04:16 AM

This is one of those "I used to hate it, now I love it" things. I used to think things should only be nullable for a reason, and you should always care if something is null - always. Null is the extra state beyond all others and I used to think it was very important to keep track of this all the time, in every layer of my application.

Later, I worked on a project (at SNSC) and was exposed to the CSLA framework. The Null object pattern was used a lot and I kind of quickly grew to appreciate it (concentrating my policy on nulls in one place.)

Over the years I have gold plated the way I use this pattern and adapted it for what I am doing at the time. I've come to recognize the following as desirable features for Null Object classes:

  • There should be a "tag" interface for the null object and an implementation. That way, when nulling for a subclass of something else, I can inherit the subclass and implement multiple null object tag interfaces (see below.)
  • They should have a static accessor to a singleton instance, so you don't have to new them up all the time, and get reference equals right.
  • They should have good ToStrings, so it's really obvious when you are looking at them in a debugger.
  • For extra credit, override any mutator or method that changes state to implement your policy: either raise an exception to catch bugs, or just silently ignore.

So, here is a typical null object implementation I have:

image

Some code for EmptyManagerAssignment:

    public interface EmptyManagerAssignment : EmptyAssignment { }

    public class EmptyManagerAssignmentImpl : ManagerAssignment, EmptyManagerAssignment
    {
        private static EmptyManagerAssignmentImpl _instance;

        /// <summary>
        /// Initializes a new instance of the EmptyManagerAssignmentImpl class.
        /// </summary>
        public EmptyManagerAssignmentImpl()
            : base()
        {
        }

        public static EmptyManagerAssignmentImpl Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new EmptyManagerAssignmentImpl();

                return _instance;
            }
        }

        public override string ToString()
        {
            return "{no Manager Assignment}";
        }

        public override int GetHashCode()
        {
            return ToString().GetHashCode();
        }
    }

In this case, the defaults the base class (ManagerAssignment) sets are just fine for the null object, but if I needed say the Name property of the null objects to be different (say I wanted to display "No Assignment" wherever I had the name of a ManagerAssignment in my UI) I would do this in the null object's constructor.

I can then use it like:

        public Program()
            : this("", new EmptyStrategyImpl(), new EmptyIndexImpl(), new EmptyManagerAssignmentImpl(), "New Program")
        {
        }

or

   if (HoldingsAssignment is EmptyAssignment /* or EmptyManagerAssignment...either way */)
   { 
      ...
   }
            

The static accessor thing ("Instance" above) is something I can't decide on. I like the fact that I'm not slamming the heap with a crap load of null objects, and I really like the identity implications of using a single instance of each null object type. But the side effect is that one object could mess up the null object for everyone else:

          if (foo is EmptyAssignment)
              foo.Name = "Look at me! I just messed up the Null object for everyone!";

Because I still like the singleton, I keep waffling back and forth on is whether or not to do something special when someone tries to update the null object:

        public override string AccountNumber
        {
            get { return base.AccountNumber; }
            set { throw new NotImplementedException("Can't update an Empty Manager Assignment...jackass"); }
        }

or

        public override string AccountNumber
        {
            get { return base.AccountNumber; }
            set { /* nop */ }
        }

It helps catch bugs, but most of those types of bugs I catch with unit tests anyway. Besides, it's a heck of a lot of work to implement overrides for everything. I could use a code generator, then regenerate all the time. Been there. Done that. Sux.

Therefore, laziness wins. I have a singleton null object. I don't check every mutator. I have a nice simple code rush template.

One final thing I will add: When using this pattern with NHibernate, I don't want NHibernate storing these null objects in the database, so I currently like to do it like this:

  • Have a field that is nullable. Tell NH about that, not the property:
    <many-to-one name="_holdingsAssignment" column="HoldingsAssignmentID" 
             access="field" cascade="save-update" />
  • Have a property that hides this nullable field from the rest of my classes:
        public virtual ManagerAssignment HoldingsAssignment
        {
            get
            {
                if (_holdingsAssignment == null)
                    return EmptyManagerAssignmentImpl.Instance;

                return _holdingsAssignment;
            }
            set
            {
                if (value is EmptyAssignment)
                    _holdingsAssignment = null;
                else 
                    _holdingsAssignment = value;
            }
        }

 

For a long time I've been meaning to check and see if there is some way to specify a surrogate for null in NHibernate, for reference types (I know how to do it with scalars.)

Does anyone else use this pattern like this? Any tricks? Does this make me look like I have too much time on my hands?


 
Wednesday, October 31, 2007 5:10:19 AM (Pacific Standard Time, UTC-08:00)
Thanks for this post.

The trick to use the access="field" in NHibernate mapping file, is a real gem, and exactly what I was looking for.

I am not using your approach with the interface. Instead I am inheriting a NULL object directly from the entity class. My entity class also contains a method that tests whether or not the supplied instance is the null object:

public class Customer : DomainObject<int> {

public class NullCustomer : Customer {
... override properties as required ...
}

public static readonly Customer Null = new NullCustomer();


public static bool IsNullCustomer(Customer cust) {
return cust!=null ? cust is NullCustomer : false;
}

.... rest of Customer
}


Cheers,
Thomas
Thomas Koch
Thursday, November 01, 2007 3:36:20 AM (Pacific Standard Time, UTC-08:00)
Thanks, Thomas.

One of the other things I added later was a class to use Dynamic Proxy to generate null object classes on the fly (and cache them), so I don't need to actually write these classes, I just say Null<Customer>.Instance. That was what the interfaces were for. I tell Dynamic Proxy to inherit from Customer, but implement the tag interface for null objects, so I can say "if (customer is EmptyEntity)" or have "interface EmptyCustomer : EmptyEntity" and "if (customer is EmptyCustomer)".

The field access in NHibernate is kind of a pain to remember though. It's really easy to forget and say "Expression.Eq("Customer", customer)" when you really mean "Expression.Eq("_customer", customer)" since you haven't actually mapped Customer the property.

I am also using NH Interceptors for validation and am thinking of just using an interceptor for this - i.e., on save just changing all "is EmptyEntity"s to nulls to save in the databases. I will post on this later if it turns out to be interesting.
Sunday, November 04, 2007 1:06:08 AM (Pacific Standard Time, UTC-08:00)
Hi Chris - I hadn't thought about the impact of using "field" access when doing queries.

I really like the idea of using an interceptor to deal with the NULL object pattern instead. When you work it out, I would certainly be interested in learning more about it.

Using NH intercepter to do validation isn't that a little like mixing business knowledge with the persistence mechanism? Personally I use a flavour of Design by Contract on my business objects, in order to ensure that their state is valid.

Cheers
Thomas
Thomas Koch
Monday, November 05, 2007 11:12:21 AM (Pacific Standard Time, UTC-08:00)
I implemented one of the pieces I needed - a multi-casting interceptor for NH - but never got around to intercepting Null Object references. I am using interceptors for validation only, at this point. I _do_ plan on doing this sometime soon, and will post about it when I am done, if you are still interested.
Tuesday, November 06, 2007 3:21:41 AM (Pacific Standard Time, UTC-08:00)
Hi - it seems that a workaround exists for the situation when you are working with field access.

Check out the NHibernate documentation for properties:
http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html_single/#mapping-declaration-property

You can actually combine the field access strategy with the property name. You only have to specify a naming strategy for NHibernate to convert the property name to the field name. That way you avoid having to use the field name in all HQLs.

NHibernate rocks. :-)

Cheers
Thomas
Thomas Koch
Wednesday, November 07, 2007 6:53:41 AM (Pacific Standard Time, UTC-08:00)
Sweet! Thanks, that's an awesome tip!
Comments are closed.