Null Object Pattern
In the Null Object Pattern, a null object replaces the check for NULL object instances. Instead of checking for null values, the Null object responds with 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 that specifies various operations to be performed and entity classes that extend this class, and also create a null object class that does not implement anything for the class. This null object class is seamlessly used in places where null checks are needed.
summary
intent
Use a null object instead of a null value. The null object implements the same interface, but performs no operations or provides default operations for requests.
Main problems solved
- The Null Object Pattern solves problems that may arise from using null values in a system, such as NullPointerException exceptions.
- It allows the system to continue running with a "safe" null object when no suitable object is available, rather than failing.
Use Case
- When the system needs to handle null objects, but also wants to avoid null checks or the handling of null values.
Implementation Approach
- Define Protocol:Define a protocol or interface that specifies the behaviors to be implemented.
- Creating concrete objects:Concrete objects that implement the protocol and provide actual behavior.
- Create Null Object:Also implement the same protocol, but provide an "empty" implementation, i.e., no meaningful operations are performed.
Key code
- Protocol or Interface:Specifies the methods that the object needs to implement.
- Concrete Object:Implement the protocol and contain actual business logic.
- Null object:Implement the protocol, but the method implementations are empty or default behaviors.
Application example
- Logging System:In a logging system, a null object may represent a logger that performs no operations.
- Default User:In a system, if there is currently no user, an empty user object can be used instead of null.
Advantages
- Avoiding null checks:Eliminates null checks in the code.
- Simplifying client code:Clients can directly call methods regardless of whether the object is null.
- Extensibility:Adding new concrete objects is transparent to clients, requiring no modification of existing code.
Disadvantages
- May hide errors:Using null objects may hide errors or exceptional conditions, making debugging difficult.
- Increases design complexity:A null object needs to be implemented for every interface that may return null.
Usage suggestions
- When the system needs to handle null values, but also wants to simplify error handling and avoid null checks, consider using the Null Object Pattern.
Notes
- The Null Object Pattern should be used with caution to ensure that it does not hide errors or mask the true state of the system.
- A null object should provide the same interface as concrete objects, so that client code can use it without any changes.
Structure
The Null Object Pattern includes the following main roles:
AbstractionObject(Abstract Object):Defines the interface expected by the client. This interface can be an abstract class or an interface.
Concrete Object(Concrete Object):Concrete classes that implement the abstract object interface. These classes provide real behavior.
Null Object:A null object class that implements the abstract object interface. This class provides default no-op behavior to be used when the object is unavailable or not applicable. It can serve as a substitute for concrete objects, replacing null checks in client code.
Implementation
We will create one that defines operations (here, the customer's name) ...AbstractCustomerAbstract class, and extendedAbstractCustomerthe entity classes of the class. Factory classCustomerFactoryBased on the name passed by the customer, returnRealCustomerorNullCustomerObject.
NullPatternDemo, our demo class usesCustomerFactoryto demonstrate the usage of the Null Object Pattern.
Step 1
Create an abstract class.
AbstractCustomer.java
Step 2
Create entity classes that extend the above class.
RealCustomer.java
NullCustomer.java
Step 3
CreateCustomerFactoryclass.
CustomerFactory.java
Step 4
UsageCustomerFactory, based on the name passed by the customer, to obtainRealCustomerorNullCustomerObject.
NullPatternDemo.java
Step 5
Run the program, output the result:
Customers Rob Not Available in Customer Database Julie Not Available in Customer Databaseother extensions