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.