Null Objects are great alternatives to The Billion Dollar Mistake. Sometimes we don't need them
TL;DR: Don't abuse patterns. Even NullObject.
Problems
Empty Classes
Namespace Polluting
Duplicated Behavior
Solutions
- Create Null Objects instantiating real-object classes.
Context
Null Object pattern is a great alternative to Nulls and IFs (Both are code smells).
The structure of the pattern tells us to create a hierarchy.
This is not really necessary, we need real objects to be polymorphic to null objects.
Inheritance is not a proper way to achieve polymorphism.
A simple solution is to create a real object behaving like a null one.
For example: '0' is numbers' null object.
'' (or "") is String's null object
An empty collection is collection's null object.
Sample Code
Wrong
abstract class Address { public abstract String getCity(); public abstract String getState(); public abstract String getZipCode(); } //Using inheritance for null objects is a mistake //We should use interfaces (when available) public class NullAddress extends Address { public NullAddress() { } public String getCity() { return Constants.EMPTY_STRING; } public String getState() { return Constants.EMPTY_STRING; } public String getZipCode() { return Constants.EMPTY_STRING; } } public class RealAddress extends Address { private String zipCode; private String city; private String state; public RealAddress(String city, String state, String zipCode) { this.city = city; this.state = state; this.zipCode = zipCode; } public String getZipCode() { return zipCode; } public String getCity() { return city; } public String getState() { return state; } } Right
//There are just "addresses" public class Address { private String zipCode; private String city; private String state; public Address(String city, String state, String zipCode) { //Looks anemic :( this.city = city; this.state = state; this.zipCode = zipCode; } public String zipCode() { return zipCode; } public String city() { return city; } public String state() { return state; } } Address nullAddress = new Address(Constants.EMPTY_STRING, Constants.EMPTY_STRING, Constants.EMPTY_STRING); //we have our null object //we should NOT assign it to a singleton, static or global //It behaves like a null object. That's enough //No premature optimizations Detection
[X] Manual
This is a semantic smell.
Tags
- Null
Conclusion
Creating Null Object classes is sometimes overdesign.
We need to create a real object.
This real object should never be global, singleton, or static.
Too many smells to avoid.
Relations
Code Smell 18 — Static Functions
Maxi Contieri ・ Nov 6 '20
More Info
Credits
Photo by Juan Davila on Unsplash
Thanks to Hernan Wilkinson for this idea on his course Diseño a la Gorra (in Spanish)
All models are wrong but some models are useful
George Box
Software Engineering Great Quotes
Maxi Contieri ・ Dec 28 '20
This article is part of the CodeSmell Series.
Top comments (0)