Code Smells 1 Null

Null Pointer Exceptions are the most often the thing OOP developer will see while their app sinks. They don’t get much help, all they tell you is that something is not there. Where you might ask and all you get is a line. In this line there are several possibilities to be null. So no real help here. Some people came up with the idea to have less information on a single line, so that the NPE can easier be identified. This is more or less a fix on the result but does not solve the root cause.
In this article I take a look at some of the root cause and how to prevent them.
These example are from the reviews I got through and part of a series of things I find in reviews. The solution and the problem itself might are my own opinions. So yours might be different.
Photo by Dawn Armfield on Unsplash
A service call might return null
Here is an example where a call to a service might return null
. How do I know that? You should always check the implementation! Sad thing to do. You should trust nobody!
So every method that returns an Object, might return null
.
1. Start
|
|
2. improve returned value
One thing I use often is to put the result of the call where an object is returned into an Optional
.
|
|
Ok, thats a little bit better, but we can do even better.
|
|
Here I skipped the logging. It is of very little use anyway.
3. moving the Optional up
The last step would be if possible to move the creation of the nullable.
|
|
You might say, “Yes, but where is the logging?”
I believe logging should only be placed here if the service is part of a 3rd party library. Here I don’t have any control over the return type or anything. But in my own implementation I would use a log aspect to capture the logging for unexpected cases. I’ll write a separate post about logging here, so stay tuned.
Null from a service
In the example above we saw, that a null
check was needed because the caller service might give us null
back. The service might look like this:
|
|
Here if the call is not successful the result is null
.
|
|
With the support of return type Optional<>
from the JPA repository functions, we can just keep the line going from end to end.
This should be changed to the following:
|
|
and then:
|
|
|
|
Basically this is all.
Left outs
To keep this example simple I omitted some mapping strategy for Entities, DTOs and Models. This would be chained to the corresponding calls to each component if needed. I also removed log calls. Those are most of the time cluttering inside a code base and increases the level of bad reading experience. From my of view, logging belongs most of the time not to the business model and should be handled behind the scenes by some abstraction. That would create a level of consistency and reduces the overall complexity for developing. Logging will be everywhere and should be as much as possible convenient.
Conclusion
We saw that we reduced the code to a bare minimum by using convenient behavior of frameworks and implicit programming. When some new will get to this code, she/he will have less problems to directly understand what is going on. But the best thing is, by using an implicit proven solution for behavior we are not creating less bugs.