Null检查空对象模式

时间:2010-03-02 23:10:03

标签: c++ design-patterns object null

Null对象模式的主要目标是确保向客户端提供可用对象。所以我们想要替换以下代码......

void Class::SetPrivateMemberA() {
    m_A = GetObject();
}

void Class::UseA() {
    if (m_A != null) {
        m_A.Method();
    } else {
        // assert or log the error
    }
}

......有了这个实现:

void Class::SetPrivateMemberA() {
    m_A = GetObject();
}

void Class::UseA() {
    m_A.Method();
}

我想到的问题是GetObject()仍然返回一个对象,一个NULL对象或其他。我喜欢不反复检查null并相信发回的对象可用的想法,但为什么我不能在第一次实现时这样做呢?

Null对象模式的优势是清除代码的信任度略有增加吗?对于第二个实现,在调用A.Method()之前检查它是否为空仍然是一个好习惯吗?

2 个答案:

答案 0 :(得分:4)

你是对的,如果你确定你永远不会返回空值,只需在第一次实现中调用方法之前跳过空检查。同样,如果在UseA()需要对空对象执行不同操作的情况下确实需要执行一些特殊操作,则无论如何都需要显式检查空对象。但是,null对象模式真正有用的是那些并不重要的情况。

以大多数观察者模式为例。如果你将你的观察者模式实现为你的类的成员,只能有一个观察者,并且想要向观察者宣告你的类做了什么,那么对于类是否为null是无效的。

这也用空容器类来说明,它们本质上是空对象模式:您只需返回一个空容器,而不是从查询返回空容器。对于迭代容器的所有条目之类的事情,它是否为空是无关紧要的,因此摆脱空检查的需要使得代码更易于维护/更具可读性。但是,如果要填充数据集的视图,仍需要显式显示不同的“无条目”。检查空容器。

为了清晰起见而编辑

一个问题只是从通话网站上查看。像大多数设计模式一样,这需要包含双方以充分利用。考虑:

public PossiblyNull GetSomethingNull()
{
    if (someBadSituation())
        return null;
    else
        return SomehowProduceSomething();
}

VS

public PossiblyEmpty GetSomethingEmpty()
{
    if (someBadSituation())
        return StaticEmptySomething();
    else
        return ProdueSomethingYay();
}

现在,您的通话代码,而不是看起来像

public void DoSomethingWithChild(Foo foo)
{
    if (foo != null)
    {
        PossiblyNull bar = foo.GetSomething();
        if (bar != null)
            bar.DoSomething();
    }
}

可以是

public void DoSomethingWithChild(Foo foo)
{
    if (foo != null)
        foo.GetSomething().DoSomething();
}

答案 1 :(得分:0)

  

有了第二个实现,是吗?   不是一个好的做法检查   它在调用之前不为null   A.Method()?

没有。如果你知道m_A不是null,那么检查是多余的;这是偏执编码的一个例子。它有什么危害?它使你的代码变得复杂 - 不必要;它使得阅读更难,更难调试。