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.field or `

`reference.method()`

. You receive the dreaded ```
NullPoi=
nterException
```

. The null object pattern uses a special object represe=
nting null, instead of using an actual `null`

. This allows you t=
o invoke field and method references on the null object. The result of usin=
g the null object should semantically be equivalent to *doing nothing.*

*=20
*### Simple Example

=20
Suppose we have the following system:

=20
=20
class Job {
def salary
}
class Person {
def name
def Job job
}
def people =3D [
new Person(name:'Tom', job:new Job(salary:1000)),
new Person(name:'Dick', job:new Job(salary:1200)),
]
def biggestSalary =3D people.collect{ p -> p.job.salary }.max()
println biggestSalary

=20
=20
When run, this prints out `1200`

. Suppose now that we now inv=
oke:

=20
=20
people << new Person(name:'Harry')

=20
=20
If we now try to calculate `biggestSalary`

again, we receive =
a null pointer exception.

=20
To overcome this problem, we can introduce a `NullJob`

class =
and change the above statement to become:

=20
=20
class NullJob extends Job { def salary =3D 0 }
people << new Person(name:'Harry', job:new NullJob())
biggestSalary =3D people.collect{ p -> p.job.salary }.max()
println biggestSalary

=20
=20
This works as we require but it's not always the best way to do this wit=
h Groovy. Groovy's safe-dereference operator (`?.`

) operator and=
null aware closures often allow Groovy to avoid the need to create a speci=
al null object or null class. This is illustrated by examining a groovier w=
ay to write the above example:

=20
=20
people << new Person(name:'Harry')
biggestSalary =3D people.collect{ p -> p.job?.salary }.max()
println biggestSalary

=20
=20
Two things are going on here to allow this to work. First of all, ```
=
max()
```

is *'null aware'* so that ```
[300, null, 400].max() =
=3D=3D 400
```

. Secondly, with the `?.`

operator, an expressi=
on like `p?.job?.salary`

will be equal to null if `salary is equal to null, or if ``job`

is equal to null or if `p`

is equal to null. You don't need to code a complex nested ```
i=
f ... then ... else
```

to avoid a `NullPointerException`

.=20

### Tree Example

=20
Consider the following example (inspired by this) where we want to calculate size, cumulative sum and cum=
ulative product of all the values in a tree structure.

=20
Our first attempt has special logic within the calculation methods to ha=
ndle null values.

=20
=20
class NullHandlingTree {
def left, right, value
=20
def size() {
1 + (left ? left.size() : 0) + (right ? right.size() : 0)
}
def sum() {
value + (left ? left.sum() : 0) + (right ? right.sum() : 0)
}
def product() {
value * (left ? left.product() : 1) * (right ? right.product() : 1)
}
}
def root =3D new NullHandlingTree(
value:2,
left: new NullHandlingTree(
value:3,
right: new NullHandlingTree(value:4),
left: new NullHandlingTree(value:5)
)
)
println root.size()
println root.sum()
println root.product()

=20
=20
If we introduce the null object pattern (here by defining the ```
Null=
Tree
```

class), we can now simplify the logic in the `size(), ``sum()`

and `product()`

methods. These methods now=
much more clearly represent the logic for the normal (and now universal) c=
ase. Each of the methods within `NullTree`

returns a value which=
represents doing nothing.

```
=20
=20
```class Tree {
def left =3D new NullTree(), right =3D new NullTree(), value
=20
def size() {
1 + left.size() + right.size()
}
def sum() {
value + left.sum() + right.sum()
}
def product() {
value * left.product() * right.product()
}
}
class NullTree {
def size() { 0 }
def sum() { 0 }
def product() { 1 }
}
def root =3D new Tree(
value:2,
left: new Tree(
value:3,
right: new Tree(value:4),
left: new Tree(value:5)
)
)
println root.size()
println root.sum()
println root.product()

=20
=20
The result of running either of these examples is:

=20
=20
4
14
120

=20
=20
Note: a slight variation with the null object pattern is to combine it w=
ith the singleton pattern. So, we wouldn't write ```
new NullTree() wherever we needed a null object as shown above. Instead we would have a =
single null object instance which we would place within our data structures=
as needed.
```

```
```

```
------=_Part_5518_518155016.1422181614272--
```