Just Say No to Nulls (or Refactoring Your Way to Programmer Bliss)

Hacker News LinkedIn Facebook Twitter by Abby Fichtner

No NullsI can’t help but feel my code is getting harder and harder to read as I wade through an ever increasing number of if != null checks before finding my way to the real logic that I actually care about…

Code Littered with if != null checks
God, doesn’t your brain just want to shut down even trying to look at it? I’ve been trying to manage this by creating an endless number of private methods whose sole purpose is to check for values in a null safe way. This at least makes my public methods easier to follow so that I can understand their logic…

Code fixed to call private methods that hide null checksEndless private methods to hide the null checks

 

 

 

 

 

 

 

But, man, now there’s even more code and all I’m doing are a few simple checks.

Doesn’t it feel like there has to be a better way?!

Well, actually yes, there is.

Stop allowing any of your methods to return nulls.

EVER.

No nulls returned, no null checks necessary. Thank you for reading.

Oh, you’re still here. Yeah, that’s a little easier said then done, isn’t it? Particularly if you’re working on existing applications with thousands of lines of null returning code. And let’s not even get started on 3rd party libraries.

The problem, of course, is that if we only manage to remove some of the null returns, developers are going to have to remember which methods can return null and which ones can’t. And the first time they’re hit with our favorite NullPointerException they’re going to go “shit!” and start adding those if != null checks all over the code again.

And so, it starts to feel like an all or nothing scenario to get out of null check hell. Either we prevent ALL of our methods from returning null and ascend into programming bliss. Or, we’re stuck with those damn null checks.

Well, the good news is that when it comes to code, improving even one small element tends to exert a positive influence on our overall design. And so, even by tackling some of our null returns, we actually end up with better, easier to maintain software. And, if we’re able to do it in a structured way — say, a policy of fixing NPEs by changing the method to not return null rather than inserting an if != null check, or taking our most heavily used component and just removing all null returns from it — then I think we can alleviate some of our brain pain.

So, okay, where do we start?

The worst culprits are the getter methods that return objects. When we have classes that return instances of other classes, which in turn return instances of yet other classes, pretty soon we wind up with a lot of method chaining

myObject.getFoo().getBar().getName().rhymesWith( “Banana” )…

and this is the worst thing we can do because there isn’t even anywhere to squeeze a null check into there.

The truth is, when we find ourselves wading through endless object hierarchies such as these, that there is what we call a code smell. And it’s a pretty good indication that we might want to revisit our design. A true OO design is composed of nice little well behaved classes that expose methods we can call on to have them do things for us. These classes abstract the nitty gritty behind the scenes details and just do it (often without the need to return any value at all).

dog.bark() not dog.getAnatomy().getVoiceBox().EmitSound( “woof” )

This is a great opportunity to see if we can’t remove some unnecessary code and complexity with a bit of encapsulation. Is it possible that the parent object can just take care of what we need without showing off how the sausage is made? If so, believe me – not only will we thank ourselves the next time we need that functionality, but so will the other developers. And, look ma, no null returns!

If not (or maybe we’re just not prepared to go quite that far at the moment), we can still ask ourselves if we really need all those getter & setter methods in the first place. Ctrl-Shift-G is one of my favorit’ist ever hot keys in Eclipse (and Resharper’s equivalent in Visual Studio). Sure, we know it’s bad design to make our instance variables public. But, are we really gaining that much when we make our variables private but then turn around and blindly provide public get/set methods for each and every one of them?

If we can lighten our code by even a few methods, not only are we removing some of those pesky null returns, we’re also reducing our maintenance costs by removing unneeded code. And that’s a Good Thing.Null Safe Get Method - returns empty object instead of null

Of course, even after all of this cleaning, we’ll still have some methods that just want to return null. But, even so, a lot we can handle by simply returning an empty instance of the object or collection where we previously would have returned null. Sure, it still requires an if != null check in the get method, but we’ve at least moved that check to a single location rather than letting it perpetuate throughout the code. And this too is a Good Thing, so we’re making our code better as we go – even if it’s 1 tiny method at a time.

What is your project’s policy on returning nulls? When you get a NullPointerException, do you fix it by adding an if != null chec
k? Or by altering the method to stop returnin
g nulls?

  • Pingback: steingarten anlegen()

  • Pingback: mercubuana()

  • Pingback: Agen Judi Terpercaya()

  • Pingback: Agen Judi Casino()

  • Pingback: free porn sex videos()

  • Pingback: free porn videos()

  • Pingback: แทงบอลออนไลน์()

  • I love emergent discourse and this is shaping up to a good one. Thanks Abby (oh, and us too).

    Sanil and AJ.NET have a similar perspective on this and so my comment replies to both.

    I think we agree that Null is an necessary entity in design. What I believe this conversation (and Abby’s initial position) tries to deal with is how do we as craftspeople best interact with Null.

    After reading AJ.NET’s thoughts I reconsidered my position of don’t pass null. I came to the conclusion that if you take AJ.NET and Sanil’s thoughts to their logical end, you wind up with minimal passing of null. And that is good for the same reason SRP is good: null-dealing-with is not the one responsibility of me (as a type).

    If you imagine the Guard aspect somehow being placed at exactly (and only) the places where nulls enter into the system – and this is the crux of the matter – then you are embracing null exactly and only where you need to.

    The astute will immediately say that there are plentiful examples where null has not entered into the system, yet we need to use null to convey pre or post conditions. My position is that pre-conditions should be conveyed using Null Object Pattern, and post-conditions should be conveyed with exceptions or NOP depending on the situation. How one conveys these null pre and post conditions in code is a matter of syntactic sugar to me.

    So I believe that every one of these threads are in essential agreement, just looking at different steps of the evolution of the solution. And I’m heartened at how each of them implies a committment to SRP.

  • Wow, interesting discussion going here :)
    Thanks abby for pointing me to here.

    Pesonally speaking, I really like null, can’t live without it. :P (Anyways, I think null as absolute zero of programming, like absolute zero in temperature)

    Well, almost every kinda solution that came to my mind has already been given here.

    Still, just have apossible work around in mind, here it is:

    //We get rid of null in a class as follows
    class NullHaterClass
    {
    private bool isNULL = false;
    public int SomeMember;
    public NullHaterClass(int param) //constructor
    {
    try
    {
    //Start construction
    SomeMember = 2 * Operation(); //Operation is something unreliable, and can cause exception
    }
    catch(Exception e)
    {
    Log.write(e.Message);
    isNULL = true;

    //set some random value to other members, if you like
    }
    }

    public int SomeFunction()
    {
    if(isNULL)
    {
    try
    {
    //init members as you have done in constructor
    SomeMember = 2 * Operation(); //again we are at mercy of Operation()
    }
    catch
    {
    //Ok, this ain’t working
    }
    //.
    //..
    // DO here what SomeFunction is reqd. to really do
    }
    }

    public int MoreFunction2()
    {
    if(isNULL)
    {
    try
    {
    //init members as you have done in constructor
    SomeMember = 2 * Operation(); //again we are at mercy of Operation()
    }
    catch
    {
    //Ok, this ain’t gonna work
    }
    .
    ..
    // DO here what SomeFunction is reqd. to really do
    }
    }
    }

    ======== Use ========
    NullHaterClass nullHater = new NullHaterClass();
    // Constructor may fail, but still object will be created
    // and valid references will are set

    nullHater.SomeFunction();

    Please comment, can this be a work around

  • Abby Fichtner

    Thanks, AJ.NET! You are correct, I totally missed the flip side of the equation when I wrote this, which is whether or not you should allow nulls passed into your method.

    But my guess is that that’s not the intention in the first place and those null values are not wanted at all. In that case, I would check the arguments and actually tell the caller that he was not supposed to pass them at all.

    That’s a great point. I like the notion of specifying a method’s contract (something we so rarely do in software) and enforcing it with assertions.

  • Hi,

    I just stumbled over your post by way of Lee’s response. I have to say that I don’t agree at all with the idea of avoiding null.

    Reasons include those you already mentioned yourself (but didn’t draw the conclusion?), like doing away with a language feature, working against people’s perceptions, and willing a whole ecosystem to change. Null is there because of a reason, it carries meaning. And no matter what, it’s just not going away.

    But anyway, I did want to make another point, which is some concern I have with your motivating example: I think it may (or may not) have mixed up the _contract_ and the _purpose_ of the method.
    Either the caller should be able to pass all those null values, then the method has to deal with them and the code is perfectly in order, crude as it might look.
    But my guess is that that’s not the intention in the first place and those null values are not wanted at all. In that case, I would check the arguments and actually tell the caller that he was not supposed to pass them at all. These checks can easily be placed in guard classes, streamlining those checks, putting them in front (cleanly separated from the actual purpose of the method), and the code would look somewhat like that:

    public BigDecimal GetDeductibleAmount(Payment payment){
    // enforce contract
    Guard.AssertNotNull(payment, “payment”);
    Guard.AssertNotNull(payment.GetPaymenType(), “payment.GetPaymenType()”);
    Guard.AssertNotNull(payment, “payment”);
    // actual implementation

    Of course the Guard class would do the simple check and throw respective ArgumentExceptions. After having made sure that all is in order the following code should look quite nice.

    The important point here is that rather than aiming to deal with every possible input the caller may provide, you force him to provide some sensible input, beyond what the language can enforce via the type system. And rather than allowing a NullReferenceException to slip from your code – which indicates a problem in that very (read _your_) code, you throw it right back at the caller, telling him that _he_ did wrong.

    What it comes down to is (in my opinion): Null is not the problem. The problem is to define what input you want to allow (i.e. define the contract) and deal with violations accordingly, _without_ letting it spoil the actual implementation.

    Just my 0,02€

    PS: Nice blog!
    AJ.NET

  • Abby Fichtner

    Hey, Rjae! How’ve you been?

    And, yes! *taps foot* I’m still anxiously awaiting your report on how this goes for you ;-)

    Would you need a post-build step if you threw a non-runtime exception, since that would give a compile error if the caller ignored it?

  • Feeling a pang of guilt not tackling that “compilation check” yet.

    I do think that – minus coding religion – there is a strong reason to avoid explicit passing of null. The issue, especially as the number of cooks in the kitchen increases, is as Abby points out: it is error prone.

    The only pervasive solution I can see is a post-build step that fails the build (perhaps with a few exception situations).

  • Abby Fichtner

    Thanks, Tim!

    All great points.

    The fact that a method can return null should be clearly documented, and IMHO if it’s not mentioned it should never return null. This is obviously much better then just the free for all “anything can return null” in which case you wind up having to check everything for null. But now you’ve got me wondering if there’s an even better way to approach this.

    My concern is that it’s still so open to human error – someone might overlook the documentation because they’re just using their editor’s autocomplete and so never even notice it. Would be nice if there was a programmatic way to force them to notice, like a compilation check.

    Might another option be to have those methods throw (non-runtime) exceptions so that the caller is forced to acknowledge it? Say a PERSON_NOT_FOUND_EXCEPTION.

  • Tim

    I’m a big fan of the Null Object Pattern, but I think there are times when it is appropriate to return null. One example is to indicate that something you are searching for cannot be found. For example:

    Person abby = findPersonByName(“Abby”);
    if (abby == null) { // handle the “not-found” case

    Now, you can have a NOT_FOUND object you return in this case instead of null, but if you forget to check the return value against NOT_FOUND you have problems.

    Person abby = findPersonByName(“Abby”);
    assert abby.getName().equals(“Abby”); // this assert may fail!

    In this case I think it’s better to get a NullPointerException than to return an object that is meaningless.

    The fact that a method can return null should be clearly documented, and IMHO if it’s not mentioned it should never return null.

  • Abby Fichtner

    Daniel,

    Thanks for pointing me to that. I had a feeling as soon as you said C# it was going to be extension methods :-) I really like those, wish they’d add them to Java. There was talk of them adding them for Java 7 but not sure whatever happened with that…

  • The “better way” may be the maybe monad. I wrote a discussion of how to apply it to C# here: http://incrediblejourneysintotheknown.blogspot.com/2008/12/maybe-monad-in-c.html

  • Abby Fichtner

    @Lee hah, thank you!

    @Everyone else, go check out Lee’s response for another take on this.

  • Hi Abby,

    I’ve taken the liberty of blogging my thoughts on this approach. I welcome your thoughts on it.

    http://leedumond.com/blog/should-we-return-null-from-our-methods/

  • Abby Fichtner

    haha, no pressure or anything! ;-)

    Thanks for stopping by – I totally blanked on the other side of the equation (passing in nulls) until our conversation. Am very interested in learning how that how that goes for you.

  • When an industry heavyweight like Jim Coplien says you give us all hope, I think it’s safe to say that you’re on to something.

    As for Don’t pass null as I mentioned this weekend: we’re planning on using post-build code analysis to report call sites in which null arguments exist. Once in place we will stop testing for null almost entirely (third-party not inclusive).

    I’ll probably blog about it so stay tuned.

    Great writing, Abby!

  • Randall

    I’ve always been of the opinion that throwing a NullPointerException ANYWHERE in your code, means you don’t really know what’s happening in the code. THAT means the code is doing things you never designed/intended it to do, and you’re out of control with the code.

    However, it’s a deep philosophical difference between members of our team. And I do mean DEEP

    Don’t exactly know why.

  • Abby Fichtner

    Oh, awesome – thanks for pointing that out!

    I am a little embarrassed to admit that Refactoring is one of those books that has gone sitting unread on my bookshelf for years. But I actually just picked it up the other day and am totally loving it so far.

    And, look at that – pg. 260 “Introduce Null Object”. Cool, thanks Peter – I will definitely check that out.

  • What you are talking about here reminds me of the “null object” design pattern.

    http://en.wikipedia.org/wiki/Null_Object_pattern

    have you ever read martin fowler’s book on refactoring? it is hands down the most useful programming book I have ever read, definitely worth a look.