I am struggling with the same problem. Here are my two cents:
Lets use the old Order and Customer classes. Suppose that we could have an Order without a Customer and we don't want our UI or Reporting code filled with "If order.Customer Is Nothing ..." (VB), so we create a NullCustomer class inheriting from Customer that can be asked for a Name and returns an empty string or a "No customer".
Since all NullCustomers would be exactly the same we want only one instance of it. If not using persistent objects a Singleton would be the obvious choice.
When using persistent objects there are two cases: entities (like Customer that have Id's) and value objects (like, for example, the Customer's Address, mapped as a Component in NHibernate).
Lets start with entities. Once created our NullCustomer would be a row it the Customers table with a Discriminator column saying "NullCustomer". Then, if we have an orders form we could fill its Customers comboBox with all the Customer records (including our NullCustomer). Each time an order selected our NullCustomer as its Customer, it would reference the same Object (and corresponding Row in the customers table). At the start of an application (before any requests are processed in a web application and maybe before deployment in a multiuser windows form application) we would have to check if we have already created a NullCustomer (with a simple query for the type) or create and save it. Also I would create a uniqueConstraint in the database using for example, the customer name and the discriminator column so that we don't have duplicate null objects.
The problem here is that I can't use a shared (static) factory method and/or a singleton pattern because that then the Customer or the NullCustomer classes would have to know about CustomerRepository (and I don't want that dependency). Here I'm supposing NHibernate generates Id's (PK's) for Customer and NullCustomer (as it inherits from Customer would have its Id automatically generated also).
Why would I need this static factory anyway? The normal use for a null object is like another option for filling an object dependency (an Order needs a Customer so instead of having a null value I put a NullCustomer). But what if I wanted to create an order that has a default NullCustomer? In a memory only world this Static Factory Method would be helpfull (_customer = Customer.NullInstance in the constructor), but in a persistent objects world ??? One solution could be passing the nullCustomer as a parameter in the constructor or use some kind of Dependency Injection technique.
Now for a null value object (for example a NullAddress embeded in a Customer) ???? Problems I see: in the database you would have duplicate values (empty strings) in the AddressStreet, AddressCity columns, and the subclass mapping is not available for components!!! So maybe in this case I would make the value object an entity.
So my conclusions:
For Entity Null Objects:
1. At application startup create the Null object and save it (if not already done)
2. When selecting a dependency for an object (like customer for an order) use a query to get all possible dependent objects (including the null object) and present the options in a user interface combobox.
3. If you don't want to spoil a Domain Model and want the Null Object instance you would have to query the database for the null subclass(NullCustomer for example) in some Application Layer and pass the instance to the domain model as a parameter.
For Value Null Objects:
1. Convert them to entity objects.
If somebody has some other thoughts please share.
Hector Cruz
|