So, continuing our look at NULL Object – let’s look at a more complicated example.
Here’s our Employee object again – this time I’ve added a method to calculate the employee’s payslip:
Now, imagine this running using our existing NullObject pattern-aware client code:
Our code won’t crash per se, but we’ll be making a real call to some payroll system with an invalid employee id – who knows what will happen? Or what if this call blocked the application whilst we waited for a result etc. etc.. Ideally, we don’t want this call to happen if the employee object is the “null” version – but we still want the method there so that the client code doesn’t need to worry about it.
Here are a few options to solve this problem: –
One way is to set a property on the Employee object to say “am I the null employee”, and the front end can check this. But that’s going against the whole Null Object pattern, so let’s discount this option right away.
Another way is to amend our GeneratePayslip method like and to check for whether this Employee is the null one:
This works – we will never call the real payslip system for a null employee – but again – to me – it seems “wrong” i.e. once again we’ve got a sort of “null check” somewhere within our code. Granted, it’s just in the one place i.e. the employee object itself, but we’ll have to do this check on every method that the Employee exposes etc. – this just seems “wrong” to me.
Here’s another option which is slightly more complex but (IMHO) is the most elegant solution:
First, we make GeneratePayslip method virtual, and then we make a new class which inherits from Employee. This class will represent our Null Employee.
Notice how we are first setting the default values for the Name and Department in the constructor – so that the base Employee class will no longer have to set them as it did in the earlier example.
Secondly, the GeneratePayslip method is now overridden so that it always returns true for the null employee.
Thirdly, I’ve set the class as Internal so that client assemblies using this Employee class will never know about the NullEmployee object – as far as they are concerned it’s just a regular Employee object, they won’t see it in intellisense, they can’t generate one themselves etc.
Now our base Employee class looks as follows:
Firstly, I’ve removed the static NullEmployee object. We could theoretically keep it but it’s probably not required now since all the “business logic” of defining the content of a null employee is in that object’s constructor now.
Secondly, the GeneratePayslip method knows nothing about whether it’s a null employee or not since this method will now always be run for “proper” employees; the null version will do nothing.
Finally, the front end still does not care about whether the Employee object is null or not. It can print out the employee’s details and even try to generate a payslip – it won’t give null reference exceptions, it won’t call external systems for “bad” employee data, and the client code doesn’t need to check if the employee is null.