What could be the root cause of a proliferation of "null checks"?

I work with a lot of Groovy code. One feature of the language is the "safe navigation operator" (?), which I think of as an inline null check. There are many things about Groovy that I like, but this is one of those features that feels like it can enable some undesirable patterns due to it's convenience. I often run into code that looks like this: def foo = bar?.field?.find { it.id? == myId } if (foo) { ... These ?s proliferate, and in various ways make things difficult to understand. I feel like this is a symptom of other design problems, but I'm having trouble articulating what those are. A few thoughts that come to my mind: There could be a lack of input validation—if something important is not present perhaps we should be handling that before we feel the need to check it many times over elsewhere in the code. The absense of something does in fact mean something, and in that case maybe we should look to something like a null object pattern. This one is maybe a bit larger, but these symptoms also seem to accompany "pass-through APIs"—where one application is just returning some value that's fed into it from a "source of truth" that might be several jumps away. In this case it feels like we're lacking a Bounded Context in DDD terms. What are people's thoughts on this? Is it actually a problem? Where might you start to address it if you see it as one?

Jan 21, 2025 - 17:54
 0
What could be the root cause of a proliferation of "null checks"?

I work with a lot of Groovy code. One feature of the language is the "safe navigation operator" (?), which I think of as an inline null check. There are many things about Groovy that I like, but this is one of those features that feels like it can enable some undesirable patterns due to it's convenience. I often run into code that looks like this:

def foo = bar?.field?.find { it.id? == myId }

if (foo) {
  ...

These ?s proliferate, and in various ways make things difficult to understand. I feel like this is a symptom of other design problems, but I'm having trouble articulating what those are. A few thoughts that come to my mind:

  • There could be a lack of input validation—if something important is not present perhaps we should be handling that before we feel the need to check it many times over elsewhere in the code.
  • The absense of something does in fact mean something, and in that case maybe we should look to something like a null object pattern.
  • This one is maybe a bit larger, but these symptoms also seem to accompany "pass-through APIs"—where one application is just returning some value that's fed into it from a "source of truth" that might be several jumps away. In this case it feels like we're lacking a Bounded Context in DDD terms.

What are people's thoughts on this? Is it actually a problem? Where might you start to address it if you see it as one?

What's Your Reaction?

like

dislike

love

funny

angry

sad

wow