When it comes to software development, especially in web development, null, will find its way into many parts of the application. Dealing with null values can become increasingly difficult, and one missing null check can bring down an entire application or website. Some languages, such as C#, will allow for nullable types (?), some will allow for opting-in to nullable types, such as Typescript, and some will allow null to be assigned to anything, such as Javascript and Java.
Alternatively, the Null Object Pattern provides a way of handling this scenario by creating a 'null-like' implementation or instance of an object or type definition which is not null but can be considered as empty, null, a non-operation, or similar. For example: many projects will use an empty string to indicate that a particular value is null-like.
Null Reference Issues
One of the worst, if not the worst, issues with null is that methods/functions will not be callable, since null has no methods. Thus, if a consumer attempts to call the method on a null value, an error will occur. The code below shows an example of this via a 'ConsoleLogger' class implementation.
In the example above, we have a class to log to the console. When we call the method, it will add some text in the front, then log your message with all leters capitalized. However, in both cases, we are able to pass null. Javascript does not compile before being loaded by the browser, and the Java version compiles succsesfully. However, when running the code, we get an error thrown, because you cannot call any methods on null. The sections below will outline two alternative approaches to handling null values: conditional checking and null object pattern.
Conditionally Checking for Null Values
A simple way to handle this issue is to check if a variable has a null value before taking some action.
In anything but the most simple cases, null checking using conditional statements will quickly become tedious as more and more if statements/branches are added. This will also make unit testing more difficult.
Null Object Pattern
Instead of checking when values are or are not null, we can use the null object pattern. In this pattern, we create a 'null-like' object by creating an instance or class which implements some interface, but conceptually can be treated as null or empty. When we use this class/instance, we can proceed without using that conditional logic for checking if values are null or not. In the code below, we have implemented Command behind the scenes to use the null object pattern, so we can trust what we receive:
In order to proceed in this manner, the underlying code needs to be implemented so that we can leverage a class or instance which follows the null object pattern. Here is an example:
This pattern can be helpful in different types of scenarios, including but not limited to:
- Removing numerous null checks and improving readability.
- Providing some default / base-case type of action.
- Providing a noop: non-operation, which can be useful when implementing a strategy or command pattern.