YouTip LogoYouTip

Null Object Pattern

# Null Object Pattern ## Null Object Pattern In the Null Object Pattern, a null object replaces the check for a NULL object instance. Instead of checking for a null value, the Null object represents a relationship that does nothing. Such a Null object can also provide default behavior when data is unavailable. In the Null Object Pattern, we create an abstract class specifying various operations to be performed and concrete classes extending that class. We also create a null object class that provides no implementation for the class. This null object class will be seamlessly used in places where a null value check would normally be required. * * * ## Overview ### Intent Use a null object to replace a null value. This null object implements the same interface but performs no operation on requests or provides a default operation. ### Problem It Solves * The Null Object Pattern addresses problems that can arise from using null values in a system, such as NullPointerExceptions. * It allows the system to continue running with a "safe" null object when a suitable object is not available, instead of failing. ### Use Cases * When the system needs to handle null objects but wishes to avoid null checks or handling null values. ### Implementation Approach * **Define a Protocol**: Define a protocol or interface that specifies the required behavior. * **Create Concrete Objects**: Implement the protocol in concrete objects that provide the actual behavior. * **Create a Null Object**: Also implement the same protocol but provide a "null" implementation that does not perform any meaningful operations. ### Key Code * **Protocol or Interface**: Specifies the methods that objects must implement. * **Concrete Object**: Implements the protocol and contains the actual business logic. * **Null Object**: Implements the protocol, but the method implementations are empty or provide default behavior. ### Application Examples * **Logging System**: In a logging system, a null object might represent a logger that performs no operations. * **Default User**: In a system, if there is no current user, a null user object can be used instead of null. ### Advantages 1. **Avoids Null Value Checks**: Eliminates null value checks in the code. 2. **Simplifies Client Code**: Clients can call methods directly without worrying about whether the object is null. 3. **Extensibility**: Adding new concrete objects is transparent to clients, requiring no modification to existing code. ### Disadvantages * **May Hide Errors**: Using a null object might mask errors or exceptional conditions, making debugging difficult. * **Increases Design Complexity**: Requires implementing a null object for every interface that might return null. ### Recommendations * Consider using the Null Object Pattern when the system needs to handle null values but wishes to simplify error handling and avoid null checks. ### Considerations * The Null Object Pattern should be used cautiously to ensure it does not mask errors or hide the true state of the system. * The null object should provide the same interface as the concrete object, allowing client code to use it without changes. ### Structure The Null Object Pattern includes the following main roles: * **Abstract Object**: Defines the interface expected by the client. This interface can be an abstract class or an interface. * **Concrete Object**: A concrete class that implements the Abstract Object interface. These classes provide the real behavior. * **Null Object**: A null object class that implements the Abstract Object interface. This class provides default, ineffective behavior for use when an object is unavailable or not needed. It can act as a substitute for the concrete object, replacing null value checks in client code. We will create an _AbstractCustomer_ abstract class that defines operations (in this case, the customer's name) and concrete classes that extend the _AbstractCustomer_ class. The factory class _CustomerFactory_ returns either a _RealCustomer_ or a _NullCustomer_ object based on the name passed by the customer. _NullPatternDemo_, our demo class, uses _CustomerFactory_ to demonstrate the usage of the Null Object Pattern. ![Image 1: UML Diagram of the Null Object Pattern](#) ### Step 1 Create an abstract class. ## AbstractCustomer.java ```java public abstract class AbstractCustomer { protected String name; public abstract boolean isNil(); public abstract String getName(); } ### Step 2 Create concrete classes extending the above class. ## RealCustomer.java ```java public class RealCustomer extends AbstractCustomer { public RealCustomer(String name) { this.name = name; } @Override public String getName() { return name; } @Override public boolean isNil() { return false; } } ## NullCustomer.java ```java public class NullCustomer extends AbstractCustomer { @Override public String getName() { return "Not Available in Customer Database"; } @Override public boolean isNil() { return true; } } ### Step 3 Create the _CustomerFactory_ class. ## CustomerFactory.java ```java public class CustomerFactory { public static final String[] names = {"Rob", "Joe", "Julie"}; public static AbstractCustomer getCustomer(String name) { for (int i = 0; i < names.length; i++) { if (names.equalsIgnoreCase(name)) { return new RealCustomer(name); } } return new NullCustomer(); } } ### Step 4 Use the _CustomerFactory_ to get _RealCustomer_ or _NullCustomer_ objects based on the name passed by the customer. ## NullPatternDemo.java ```java public class NullPatternDemo { public static void main(String[] args) { AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob"); AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob"); AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie"); AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura"); System.out.println("Customers"); System.out.println(customer1.getName()); System.out.println(customer2.getName()); System.out.println(customer3.getName()); System.out.println(customer4.getName()); } } ### Step 5 Execute the program to output the result: Customers Rob Not Available in Customer Database Julie Not Available in Customer Database
← Strategy PatternState Pattern β†’