Code Smell 126 — Fake Null Object
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 the numbers' null object.
'' (or "") is String's null object
An empty collection is the 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
// You 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);
// You have your null object
// You should NOT assign it to a singleton, static or global
// It behaves like a null object. That's enough
// No premature optimizationsDetection 🔍
[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
Code Smell 17 - Global Functions
More Information 📕
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
This article is part of the CodeSmell Series.




