Null Object Pattern

Null Object Pattern

Photo by Ben Hershey on Unsplash

The null object pattern replaces null values within a specific object with a custom null object that is of the same class. The null object's fields will have default values, preventing it from causing a null pointer exception.

Example

f we don't use a null object, then we have to check for a non-null condition.

    private static void printVehicleDetails(Vehicle vehicle) {
        if (vehicle!=null){
            System.out.println("Seating capacity: " + vehicle.getSeatingCapacity());
            System.out.println("Seating capacity: " + vehicle.getTankCapacity());  
        }
    }

If we use a null object, there is no need to perform null checks

    private static void printVehicleDetails(Vehicle vehicle) {
        System.out.println("Seating capacity: " + vehicle.getSeatingCapacity());
        System.out.println("Seating capacity: " + vehicle.getTankCapacity());
    }

Design Null object

Designing a null object is a straightforward task. You can achieve this by utilizing the same interface that the real object implements or by extending the same abstract class. In both cases, it is necessary to override the methods and establish default implementations.

UML for Null Object in general:

UML for Vehicle example:

Code Implementation

Interface:

public interface Vehicle {
    int getTankCapacity();
    int getSeatingCapacity();
}

Real Object (car)

public class Car implements Vehicle{
    @Override
    public int getTankCapacity() {
        return 40;
    }

    @Override
    public int getSeatingCapacity() {
        return 5;
    }
}

Null Object

public class NullVehicle implements Vehicle {
    @Override
    public int getTankCapacity() {
        return 0;
    }

    @Override
    public int getSeatingCapacity() {
        return 0;
    }
}

Usage

public class Main {
    public static void main(String[] args) {
        Vehicle vehicle = VehicleFactory.getVehicleObject("bike");
        printVehicleDetails(vehicle);
    }

    private static void printVehicleDetails(Vehicle vehicle) {
        System.out.println("Seating capacity: " + vehicle.getSeatingCapacity());
        System.out.println("Seating capacity: " + vehicle.getTankCapacity());
    }
}

Conclusion

With the help of null objects, we can avoid null checks. Null objects have default behavior, and we can customize this behavior according to our needs.