Reputation: 346
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?
Upvotes: 3
Views: 446
Reputation: 11927
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.
Upvotes: 1
Reputation: 393841
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);
}
}
Upvotes: 0