I love this code smell. First I find the solution to be fascinating. Second, the indicator (checking for null) is often NOT a problem, more so than in most code smells. But that's the beauty of code smells. They give us an indication that something MIGHT be amiss, but we have to check it out ourselves and decide if something really does need to be corrected.
So let's start by looking at an example of the problem:
Here we have some sample code from an eCommerce site. It's fairly typical on these sites to allow you to check out as a guest and not create an account.
Here is one such algorithm, where we determine the discount to apply to the order. If the user is checking out as a guest (the customer object is null) then we use a default discount, otherwise we use the customer's earned discount.
Looking at this method our null check seems fairly harmless. This is a reasonable way to implement the necessary functionality.
Now let's look at another method from that same class:
Here we have the same thing going, we have to know if the user is checking out as guest or not. And now we can start to see part of the problem. Our null checks are littered around our code. We can assume that this logic is common, so we have to frequently check to see if the customer is null for the order.
This is our code smell. Frequent checks for the same null.
So what do we do about this? There's a very cool fix we can apply here by using what's called a Null Object. Null objects are special classes which replace a null value in our code so that we can simplify our code. Let's see how this is done.
First we create a NullCustomer class. This is our Null Object. Notice the two methods it has. Remember where those methods are used?
Next we create our NullCustomer, and use it instead of setting the customer to null. This way, we do our null check only once.
And now, we can go back to our order class and fix the getDIscount and processOrder methods. Because our Null Object implements those methods, we no longer have to do any kind of check in our code. That makes our core business logic simpler.
In fact, our getDiscount has become so simple, we may consider dropping it altogether.
This is the power of the Null Object used to solve the Null Check code smell. I really think this is a cool technique to solve a relatively common problem.