Extending the builder pattern with null safety

Safety first

As we learned in the previous blog Achieve thread-safety with immutability the builder pattern is a very good design to follow to make your code safer. Another common, perhaps the most common, error that occurs in applications is the NullPointerException. So in this article, we are going to look at how we can use design to eliminate null.

I call it my billion-dollar mistake… At that time, I was designing the first comprehensive type system for references in an object-oriented language. My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
– Tony Hoare, inventor of ALGOL W.What is an Optional?

Java 8 comes with some truly amazing new features that you definitely should check out and start using already if you aren’t. One of these features is java.util.Optional[1].

An optional wrap an object and provides a couple of really useful methods for dealing with that object in a safe way. Optional’s are by design very declarative which makes the code that uses it very easy to read, and it also works very well with java.util.stream[2], another great Java 8 feature. But the main benefit of using it is that you do not have to check for null as long as you use it properly. If you start adopting this throughout your application then you shouldn’t need to check for null anymore, doesn’t that sound great?

We can use two different methods to create an Optional.

The first method creates an Optional containing the object and if the object was null it creates an empty Optional. The second option throws a NullPointerException if the object is null. I recommend mostly using the first option as the whole point of Optional is to eliminate NullPointerExceptions. But if you wanna make sure that your Optional always contains an object then, of course, feel free to use the second version.

When using an Optional we have a couple of different methods that we can use.

Before we continue with more examples, let’s integrate this into our builder pattern. We extend our ImmutablePerson so that a person can have a website. We also realize that a person doesn’t necessarily need to have a list of favorite dishes. So we end up with the following fields.

The full class looks like the following.

Many advocators of Optional believes that Optional’s should only be used as a return value, and we follow that rule with our ImmutablePerson class. The getters for our class will never have to be checked for null because if the value is not mandatory, we always wrap it in an Optional. Because the object is immutable, an update to the object have to go through the builder pattern with calling build(). In our build method we use Preconditions[3] from Guava to always verify the state. If the mandatory fields would be null, we would throw an IllegalStateException. After that, it goes through the private constructor for the ImmutablePerson class where we verify the arguments again (beacuse they could have been concurrently updated after our checks in build() and throw an IllegalArgumentException if they would be null.

Our website class looks like the following.

Optional during use

So we have our thread and null safe object. Let’s put them to use by writing a test verifying that they really are safe from null.

It works! We are not allowed to create objects where mandatory fields are null. And as shown in the second test we can easily perform tests with the declarative methods of Optional.

My favorite features of the Optional is the map and flatMap methods which takes a function that maps it to another value. It really makes it easy to use them.

Final words

So as you can see (and hopefully agree), Optional is not only good for adding safety against null. Personally, it has completely changed the way I write code. I would love to hear your opinions on it.

The code is available on GitHub.

If you enjoyed the post, please help me out by giving it a like and sharing it on social media.


You may also like

Leave a Reply

Your email address will not be published. Required fields are marked *