If I query for an object say for an Animal and the returned object is not null but contains null variables is that wrong? For instance I can call animal.getDeathDate()
; and since it's not dead yet it returns null. For a Turtle getFlightSpeed()
would return null since it's unable to fly until it has the Turtle rocket pack added. Etc, etc.
I thought that this was a bad way to do things as it will often cause the need for a lot of null checks while calling the methods of the object to verify that they contain non-null values. Are there any links to information about this that could inform both myself and my coworkers further?
The Null object pattern is a design pattern that simplifies the use of dependencies that can be undefined. This is achieved by using instances of a concrete class that implements a known interface, instead of null references.
In software engineering, anti-patterns include the big ball of mud (lack of) design; the God Class (where a single class handles all control in a program rather than control being distributed across multiple classes); and Poltergeists (ephemeral controller classes that only exist to invoke other methods on classes).
In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral ("null") behavior. The null object design pattern describes the uses of such objects and their behavior (or lack thereof).
Returning null is often a violation of the fail fast programming principle. The null can appear due to some issue in the application. The issue can even go to production if the developer has not implemented proper exception handling, which can help quickly detect the issue.
null
is often ambiguous. Was the field uninitialized yet or it just has no value?
It's often better to have some predefined constant for uninitialized / irrelevant fields.
Even better is to have one class have only one responsibility. Methods like getFlightSpeed()
should not be inherited, rather come from implementing an interface (methods like getDeathDate()
, though, should have a predefined constant returned when Animal
is still alive).
As brought by google-guava docs:
Doug Lea (author of java.util.concurrent
package) said that Null s**ks
.
Also sir C. A. R. Hoare, inventor of the null
reference said: I call it my billion-dollar mistake
.
That's some wide shoulder to lay upon.
Returning null
for the death date for an alive animal is perfectly reasonable, but in cases like this I find it better to offer a boolean death check:
public boolean isDead() {
return deathDate != null;
}
This offers a reasonable way of checking the death-ness of an instance without a clumsy null check of the attribute:
// this is ugly and exposes the choice of the value of the field when alive
if (animal.getDeathDate() != null) {
// the animal is dead
}
With the isDead()
method in place, you would be within your rights to do this:
public Date getDeathDate() {
if (deathDate == null)
throw new IllegalStateException("Death has not occurred");
return deathDate;
}
Regarding the turtle's flying speed, you could apply the same approach, although I would argue that there's a problem in your class design - not all animals fly, so the Animal
class shouldn't have a getFlyingSpeed()
method.
Instead, use something like this:
interface Flyer {
Integer getFlightSpeed();
}
class Animal {}
class Turtle extends Animal {}
class Eagle extends Animal implements Flyer {
public Integer getFlightSpeed() {
//
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With