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();
    }
}

在上面的代码中,我创建了一个 DummyChild 类,这样每当调用 getObj() 以获取正确的类对象时,我不会返回 NULL,而是返回 dummyClass 对象(单例)。这消除了我的代码中的 NULL 检查,从而消除了由于这种情况而产生的分支。

这是使用 NULL 对象模式的正确位置还是应该使用 NULL 方法?

4

2 回答 2

1

当语义上有意义时,使用接口的“什么都不做”实现是对模式的一种很好的使用。问题是,什么时候这样做才有意义?

我使用的关键问题是:“我是在建模 0-1 关系还是 1-1 关系”。在第一种情况下,使用 Optional 来传达这一事实让开发人员非常清楚,并帮助我们获得编译时支持。如果我们正在建模一个 1-1 关系,并且在某些情况下我们的真正意思是“什么都不做”,那么通过Liskov 替换原则的“什么都不做”实现是一个非常优雅的解决方案。

有关数据建模中基数的讨论,请阅读以下书籍片段:Cardinality。简而言之,基数是两个事物之间的关系可以表示的事物的数量。例如,在为汽车建模时;我们希望它有多少个引擎?0-1 表示汽车可以有零个或一个引擎,1-1 表示汽车必须只有一个引擎,0-many 表示汽车可以有 0、1、2、3、4 .. 。 引擎。

于 2018-07-11T09:37:32.470 回答
0

您可以使用Optional而不是重新发明轮子:

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);
    }
}
于 2018-07-11T09:26:51.610 回答