The Null Object Pattern involves using a special object place-marker object representing null. Typically, if you have a reference to null, you can't invoke
reference.method(). You receive the dreaded
NullPointerException. The null object pattern uses a special object representing null, instead of using an actual
null. This allows you to invoke field and method references on the null object. The result of using the null object should semantically be equivalent to doing nothing.
Suppose we have the following system:
When run, this prints out
1200. Suppose now that we now invoke:
If we now try to calculate
biggestSalary again, we receive a null pointer exception.
To overcome this problem, we can introduce a
NullJob class and change the above statement to become:
This works as we require but it's not the best way to do this with Groovy.
?. operator allows Groovy to avoid the need to always create a special null object. So this code is all we need:
Consider the following example (inspired by this) where we want to calculate size, cumulative sum and cumulative product of all the values in a tree structure.
Our first attempt has special logic within the calculation methods to handle null values.
If we introduce the null object pattern (here by defining the
NullTree class), we can now simplify the logic in the
product() methods. These methods now much more clearly represent the logic for the normal (and now universal) case. Each of the methods within
NullTree returns a value which represents doing nothing.
The result of running either of these examples is: