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.
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:
- 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.