Null Object Design Pattern
A Null Object is an object with defined neutral ("null") behavior. The Null Object design pattern describes the uses of such objects and their behavior (or lack thereof). (Wikipedia)
- AbstractClass defines abstract primitive operations for client’s collaborator that concrete implementations have to define. It optionally implements default behavior for the interface common to all classes, as appropriate.
- RealClass implements AbstractClass performing some real actions that client expects.
- NullClass implements AbstractClass and does nothing in order to provide a non-null object to the client that can be substituted for a real object
- Client has a reference to abstract class implementation and collaborates with it and does not care if the implementation is a null object or an real object.
If some clients expect the null object to do nothing one way and some another, multiple NullObject classes will be required. If the do nothing behavior must be customized at run time. A Null Object does not transform to become a Real Object. If the object may decide to stop providing do nothing behavior and start providing real behavior, it is not a null object. The null behavior is not designed to be mixed into an object that needs some do nothing behavior. It is designed for a class which delegates to a collaborator all of the behavior that may or may not be do nothing behavior.
- The Null Object Pattern is used to avoid special if blocks for do nothing code, by putting the “do nothing” code in the Null Object which becomes responsible for doing nothing. The client is not aware anymore if the real object or the null object is called so the ' if ' section is removed from client implementation.
- Some collaborator instances should do nothing
- Can be used to act as a stub for testing
- Can be used to remove old functionality by replacing it with null objects, as a result the existing code does not need to be touched.
- A Null Object is predictable and has no side effects: it does nothing.
- Provides intelligent do nothing behavior and hiding the details from its collaborators
- Provide an object as a surrogate for the lack of an object of a given type.
- Clients can treat real collaborators and null collaborators uniformly.
- Can make errors/bugs appear as normal program execution.
- Can be difficult to implement if various clients do not agree on how the null object should do nothing as when your AbstractObject interface is not well defined.
- Null Object pattern can be regarded as a special case of the State and the Strategy pattern.
- Null Object pattern is more likely to be used in conjunction with the Factory Method pattern.
- Null Object class is often implemented as a Singleton since a null object usually does not have any state.
- Null Object can be used to allow a Visitor to safely visit a hierarchy and handle the null situation.
- The use of a Null Object can be similar to that of a Proxy, but the two patterns have different purposes. A proxy provides a level of indirection when accessing a real subject, thus controlling access to the subject. A null collaborator does not hide a real object and control access to it, it replaces the real object. A proxy may eventually mutate to start acting like a real subject. A null object will not mutate to start providing real behavior, it will always provide do nothing behavior.