Null person

When I first had a look at the wrapper Boolean data type in Java a funny thought came to my mind about the tri-state nature of a boolean (Why null becomes a possible value?). Later applied the thought to any other data type which is nullable and got funny analogies. Since Object Oriented Programming was related directly to real world, I came up with the following analogy.

Every morning you get your newspaper delivered at your doorstep. The paper boy rings the bell and leaves the paper at your doorstep. Let us assume that the door bell is the function call and newspaper is the object you receive. What happens if you wont get the newspaper delivered?; quite obvious, the paper boy either won’t arrive or will come to your doorstep and communicate why the paper is not delivered.

What would happen if instead of the above scenario the paper boy arrives at your doorstep and delivers a null newspaper? You must receive the newspaper & assert that it is not null and decide to do some other activity, else your day ends abruptly because a null pointer is thrown when you tried to read the newspaper. Now let us not limit this to just newspaper, what about the need to worry about nulls every where? Would not you be driven crazy that you will have to worry about null mails, null phone calls, null water bottles?

This is what happens with many Java programmers where there is some point in their life they had dealt with a sticky, messy null pointer exception caused by some one who had made use of null for a boolean as a logic flow alternative to the true and false state. More worse is the SQL boolean data type having unknown and null as possible values.

So much of code has been written with guard clauses to prevent these nasty null pointer exceptions from getting in and eventually cost 3 extra lines of code in almost all critical business logic methods. Lately I have seen a positive trend among peers in the way we treat nulls. I have seen many consiously avoiding nulls and replacing them with empty objects, Null object pattern or special instances to handle ambiguities. When we move to newer (I would say newly adopted) languages I believe null will cease to exist.

4 Comments

  1. How about design by contract? Write a postcondition that the return value cannot be null. I think this is the best way to avoid null checks throughout application. In addition, you have others benefits using DbC.

  2. I suggested DbC because you can write preconditions and postconditions for a method, eliminating unnecessary and redundant verifications.

    public BusinessObject Foo(int param) {	
    	// do stuffs
    	return something;
    }
    
    int x = getNumber();
    BusinessObject obj = Foo(x);
    obj.doSomething();
    

    Eventually you have NullPointerException and add a verification, but you call Foo() many times.

    // Case 1
    int x = getNumber();
    BusinessObject obj = Foo(x);
    if (obj != null) {
    	obj.doSomething();
    }
    
    // Case 2
    int x = getAnotherNumber();
    BusinessObject obj = Foo(x);
    if (obj != null) {
    	obj.doSomething();
    }
    
    // Case 3
    int x = getNumber();
    BusinessObject obj = Foo(x);
    if (obj != null) {
    	obj.doSomething();
    }
    else {
    	// try some crazy stuff
    }
    

    “Case 3” has a different treatment about null object, that is a mess!
    So, you move the verification to the Foo method eliminating redundance.

    public BusinessObject Foo(int param) {	
    	// do stuffs
    	if (something == null) {
    		throw new Exception();
    	}
    	else {
    		return something;
    	}
    }
    

    All right, so you try this:

    // Case 1
    BusinessObject obj = Foo(1);
    obj.doSomething();
    
    // Case 2
    BusinessObject obj = Foo(2);
    obj.doSomething();
    
    // Case 3
    // Now here you have an Exception!
    BusinessObject obj = Foo(-3);
    obj.doSomething();
    

    Look at Foo()

    public BusinessObject Foo(int param) {	
    	something = privateMethodThatCanReturnNull(param);
    	// do stuffs
    
    	if (something == null) {
    		throw new Exception();
    	}
    	else {
    		return something;
    	}
    }
    

    And you look at privateMethodThatCanReturnNull and found this:

    private BusinessObject privateMethodThatCanReturnNull(int param) {
    	if (param > 0) {
    		return new BusinessObject(param);
    	}
        else {
            return null;
        }
    }
    

    You can put the verification here:

    int x = getNumber();
    if (x > 0) {
    	BusinessObject obj = Foo(x);
    	obj.doSomething();
    }
    

    But it is like the NullPointerException verifications. So you move the verification at the beginning of the Foo() method.

    public BusinessObject Foo(int param) {	
    	// precondition
    	if (param <= 0) {
    		throw new IllegalArgumentException();
    	}
    	// do stuffs
    	BusinessObject something = privateMethodThatCanReturnNull(param);
    	// do stuffs
    
    	// given it pass the precondition, i must supply a non null object
    	// postcondition
    	if (something == null) {
    		throw new Exception();
    	}
    	else {
    		return something;
    	}
    }
    

    If we provide the right parameters we suppose that will work correctly. This is the client/supplier relationship.

    Using Contract4J framework

    @pre("param > 0")
    @post("return != null")
    public BusinessObject Foo(int param) {
    	BusinessObject something = privateMethodThatCanReturnNull(param);
    	// do stuffs
    	return something;
    }
    

    It’s recommend to use contracts on all business classes. Validate user-inputs before the parameters reach your business layer.

    You still having an Exception on calling Foo(-3) but it’s because the client don’t honors his contract.

    “So much of code has been written with guard clauses to prevent these nasty null pointer exceptions from getting in and eventually cost 3 extra lines of code in almost all critical business logic methods.”

    Actually, there is no way to escape from the verifications but it’s important to use the DbC style in the right places.
    If your language don’t has native support for DbC you can use a framework. Eiffel has native support for DbC and .Net has the System.Diagnostics.Contracts namespace. For Java i think the best is Contract4J framework but there are others.

    You can find all about DbC in this book: Object-Oriented Software Construction (second edition) by Bertrand Meyer

    Eiffel Software presentations, that is a good introduction.
    Part one
    Part two

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s