Lesson from Object Bootcamp - The Null-Object Pattern
I thought I would share a few of the things that I learned while going through Object Bootcamp last week. The first, and probably the biggest thing was the idea of memory equivalence. This can be show easily by also showing another thing that I learned which was how to use the Null-Object design pattern. This is a pattern that I have read about, but have never really seen used until now.
The Null-Object pattern is used to return a null object instead of a null. The former is better since it removes the chance of encountering a NullPointerException. The idea is to return an object that basically does nothing, i.e., its methods simply return default, useless data. The trick is in how to implement this object.
Say we have an email object that represents an email address and can send an email when the appropriate method is called; however, the email address may or may not exist. So instead of returning null, we want to return a null-object when we do a search. So here is our email object:
public class email {
private String emailAddress;
public boolean sendEmail(String message) {
// send out email using Javamail or something
}
}
Now here is the same class utilizing the null-object pattern, the trick is the static instantiation.
public class Email {
public static Email noEmailAddress() {
public boolean sendEmail(String message) {
return false;
}
};
private String emailAddress;
public boolean sendEmail(String message) {
// send out email using Javamail or something
}
}
The sensible default is to always answer false (i.e., the email was not sent) when sending the sendEmail() message to the Email object. This way, it does what we expect and doesn’t break anything.
*Update:* ignore the following since, although it does make the code more readable, it breaks with the intention of the null-object pattern. As pointed out to me in the first comment.
Another cool feature of using the null-object pattern is that we can now write code that looks like this:
if (returnedEmailAddress==noEmailAddress) {
// do something about it
}
Instead of checking to see if the result is null.
if (returnedEmailAddress==null) { //do something }
This makes the code a lot more readable and understandable. Just by looking at the code, we can understand immediately what happened. The trick to this is that we only ever instantiate one noEmailAddress object. This allows us to check that the two references point to the same space in memory and results in a very nice equivalency check instead of having to use returnedEmailAddress.equals(noEmailAddress).