A military installation from Soviet times in Northern Estonia

Null Object and Optional

Ürgo Ringo
Wise Engineering
Published in
2 min readApr 14, 2020

--

Null Object and Optional are both ways to avoid nulls. In the following post we will compare these two approaches to see when one or the other is more suitable.

Null Object

Null Object pattern is nice as it hides away the special case of not having a value for something. So ideally we should be able to avoid all ifs for null checks. This works nicely when we can replace normal behavior with a noop implementation. However, it does not work so well when we need to access some data on the object.

For example, we have a Customer class like this:

class Customer {
static final Customer NULL = new Customer() {
Instant registrationDate() {
return null
}
}
Instant registrationDate() {...}
}

Customer.NULL allows us to avoid nulls when there is no Customer. However, when we need to get the registration date we are back in the null land.

One solution is to turn this from plain getter into something that has more behavior. If the question we want to ask from Customer is: “Did you register before date X?” we can just add a method like registeredBefore(Instant). It may seem like simple cosmetics. However, this can be a nice strategy how to introduce behavior into a class that originally looked like a plain struct.

Optional antipatterns

What if we still need the registered date value? For example, to format the date value as a String for our JSON response.

One way how to avoid null checks is wrapping the result in an Optional:

Optional.ofNullable(
customer.registrationDate()
).map(
dateTimeFormatter::format
).orElse(null)

Although I have used this style quite a lot it is not very elegant. In fact this is not any better than doing plain “ifs” for nulls. We still need to be alert that some values may be null everywhere in our codebase.

Another antipattern I have used is adding hasValue() method to Null Object. This again defeats the purpose of Null Object pattern and should not be used.

Null Object with Optional

For the scenarios like above returning Optional makes more sense than forcing client code to do that. Otherwise we have just replaced the “if” with slightly fancier code but achieved nothing else.

So Optional and Null Object can nicely complement each other. Using Null Object for more complex value objects and have query methods return Optional where no other sensible value can be used.

P.S. Interested to join us? We’re hiring. Check out our open Engineering roles.

--

--

Ürgo Ringo
Wise Engineering

Have been creating software for 20 years. Cofounded a software consultancy, worked as an IC and team lead at Wise. Currently working at Inbank.