Consider a batch operation that may or may not take long time to do its job (depends on data).
A user can register an OPTIONAL listener for tracking job progress.
NOTE: listener registration is totally optional and user may want to
call the job without registering any listener.
Q: Which of the following solutions are your preference and why?
EDIT: the concern here is performance vs clean code. some say, checking null reference (solution 1) is faster compare to second solution. but second solution is cleaner and more understandable. I would like to have your opinion.
No 1: Allow null listener and always check if listener is not null, then call it.
doMyBatchJob() {
if (listener != null) {
listenr.progressStarted(params);
}
while (x) {
if (listener != null) {
listener.progressUpdated(current, expected)
}
}
if (listener != null) {
listenr.progressFinished(params);
}
}
No 2: Implement a dummy listener, and register it if user didn’t pass his/her own listener.
so that can call listener without checking for null object.
DummyListener {
public void progressStarted(params) { //DO NOTHING }
public void progressUpdated(current, expected) { //DO NOTHING }
public void progressFinished(params) { //DO NOTHING }
}
doMyBatchJob() {
listener.progressStarted(params);
while (x) {
//Do a single unit of the batch operation
// ... code omitted here
listener.progressUpdated(current, expected)
}
listener.progressFinished(params)
}
You are correct in your concern that
if x==nullis a code smell, it definitiely is!There are very valid reasons for using the
Null Objectpattern, one is to keep from littering your code withif (x == null)noise that is usually less business related and more poor design related.NULLmeans an absence of a value not a default value.I don’t think you are taking the
Null Objectpattern far enough.Never return null and you never have to check for it
First off never
return nullfrom a method and never haveif x == nullin your code. Both are sure signs of poor design.nullreferences andNPEshould be an error that should be resolved where it doesn’t happen.Never accept null and you never have to check for it.
Have methods that
return nullreturn aNull Objectand have things that accept null and might processnullreferences haveNull Objectimplemenations to process theNull References.In your case your
Dummyobject would not just not do anything, it should report to the log warnings that it has encountered anulland something should be done about it.Use a good JSR305 library to annotate your methods so that they dont’ accept nulls.
I have the
com.google.code.findbugsmaven dependency in every Java program I create, no matter how trivial, then I can decorate every method and method parameter with@NONNULLand not have to worry about writingif x == nullever again!If you have 3rd party code that returns
nullwrap it and use the JSR305 annotations.Use the Guava
Preconditions.checkNotNull()with astaticimport so you can docheckNotNull()on all parameters that are marked@Nonnnull, you can even include a descriptive error message about what was,nulland why it should not be or whatever.And smugly think about how poorly designed their code is.