3
interface Parent{
    void process();
}

class Child1 implements Parent{
    void process(){
        //process by method 1
    }
}


class Child2 implements Parent{
    void process(){
        //process by method 2
    }
}

class DummyChild implements Parent{
    void process(){
        //do nothing
    }
}
class D {
    Parent getObj(){
        if(condition1){ 
            return new Child1();
        }
        else if(condition2){    
            return new Child2();
        }
        else
        return new DummyChild();
    }
    public static void main(String[] args){
        Parent obj = getObj();
        obj.process();
    }
}

In the above code, I have created a DummyChild class so that whenever getObj() is invoked for fetching the correct class object, instead of returning NULL I return the dummyClass object(singleton). This eliminates the NULL check in my code thereby removing the branching because of this condition.

Is this a correct place of using the NULL object pattern or should I use the NULL approach?

3
  • Use java.util.Optional. Commented Jul 11, 2018 at 9:25
  • In general yes, that is Null design pattern. While, it is valid, poorly written codes can still result in NullPointerException - this design pattern doesn't stop anyone from passing in a null reference. For robust solution, use Optional as recommended. Commented Jul 11, 2018 at 9:28
  • While I love Optional it still forces some branching on the client, which the null pattern doesn’t. There are pros and cons. But we’re turning this question into a more opinion-based one than it was when it was asked. Commented Jul 11, 2018 at 9:37

2 Answers 2

1

Use of a 'do nothing' implementation of an interface is a good use of the pattern when it semantically makes sense to do so. The question is, when does it make semantic sense to do so?

The key question that I use is: 'am I modelling a 0-1 relationship or a 1-1 relationship'. In the first case, then using Optional to communicate that fact makes it very clear to developers and helps us with compile time support. If we are modelling a 1-1 relationship, and we really mean 'do nothing' in some case then the 'do nothing' implementation that passes the Liskov substitution principle is a very elegant solution.

For a discussion on cardinality in data modelling, have a read of the following book snippet: Cardinality. In brief, cardinality is the number of things that a relationship between two things can represent. For example, when modelling a car; how many engines would we expect it to have? 0-1 would mean that a car can have zero or one engine, 1-1 would mean that a car must have exactly one engine, 0-many would mean that the car could have 0, 1, 2, 3, 4 ... engines.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. What do we mean here by 0-1 and 1-1 relationship?
@P3A good call; I have assumed that knowledge. Start by having a read of en.wikipedia.org/wiki/Cardinality_(data_modeling) and I will also add a bit more detail to the answer.
0

You can use Optional instead of re-inventing the wheel:

class D {
    Optional<Parent> getObj(){
        if(condition1){ 
            return Optional.of(new Child1());
        }
        else if(condition2){    
            return Optional.of(new Child2());
        }
        else {
            return Optional.empty();
        }
    }
    public static void main(String[] args){
        Optional<Parent> obj = new D().getObj();
        obj.ifPresent(Parent::process);
    }
}

4 Comments

I totally agree using Optional, but I would say most of the time it's more intuitive to wrap the value with Optional when trying to call the method, rather than a "provider" to return an Optional. Just an opinion though.
Thanks for the above code but I have a doubt. Suppose I have to call a number of function depending whether the object is null or not. Instead of writing if(NULL != obj) you have written obj.ifPresent(Parent::process), this doesn't make my code clean, and in case of calling multiple functions I will have to write something like obj.ifPresent(Parent::someotherinterfacefunction). However in my code above, all these checks are removed. So what's ur suggestion on this?
@Jai it's a tradeoff. If you are calling the method that returns the potentially null instance from multiple places, wrapping it with an Optional each time could be annoying. On the other hand, changing multiple such methods to return an Optional can be equally annoying.
@P3A there are various Optional methods you can use (orElse, orElseThrow, etc...), depending on the specific scenario.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.