包含空变量的Java对象是否为反模式?如果是这样的话?

时间:2013-08-05 13:57:35

标签: java anti-patterns

如果我查询一个对象说一个Animal并且返回的对象不是null但是包含空变量那么错误?例如,我可以致电animal.getDeathDate();因为它还没死,但它返回null。对于Turtle getFlightSpeed()将返回null,因为它在添加了Turtle火箭包之前无法飞行。等等。

我认为这是一种糟糕的做事方式,因为在调用对象的方法以验证它们包含非空值时,通常会导致需要大量的空检查。是否有任何关于此信息的链接可以进一步告知我和我的同事?

9 个答案:

答案 0 :(得分:4)

null经常含糊不清。该领域尚未初始化还是没有价值?

为未初始化/不相关的字段设置一些预定义的常量通常会更好。

更好的是让一个班只有一个责任。像getFlightSpeed()这样的方法不应该继承,而是来自实现一个接口(像getDeathDate()这样的方法,但是,当Animal还活着的时候应该有一个预定义的常量。)

As brought by google-guava docs

Doug Lea(java.util.concurrent包的作者)说Null s**ks

同样sir C. A. R. Hoarenull引用的发明者说:I call it my billion-dollar mistake

这是一个广泛的肩膀。

答案 1 :(得分:4)

为活着的动物的死亡日期返回null是完全合理的,但在这种情况下,我发现提供布尔死亡检查更好:

public boolean isDead() {
    return deathDate != null;
}

这提供了一种合理的方法来检查实例的死亡率,而不会对属性进行笨拙的空检查:

// this is ugly and exposes the choice of the value of the field when alive
if (animal.getDeathDate() != null) {
    // the animal is dead
}

使用isDead()方法,您有权这样做:

public Date getDeathDate() {
    if (deathDate == null)
        throw new IllegalStateException("Death has not occurred");
    return deathDate;
}

关于乌龟的飞行速度,你可以采用相同的方法,虽然我认为你的班级设计存在问题 - 并非所有动物都飞,所以Animal班不应该有{{1 }} 方法。

相反,请使用以下内容:

getFlyingSpeed()

答案 2 :(得分:1)

Null有时可以是表示对象缺少特定属性的完美合理方式。

但是,允许检查很有用。

对于数组或List,通常最好使变量始终为非null,但可以指向空列表。否则,有必要检查变量是否为非null并且列表中包含成员。

答案 3 :(得分:1)

我认为这不对。作为类比,请考虑NULL in SQL

的语义
  

记住NULL意味着什么的一个好方法是记住它   信息,“缺乏价值”与“价值”不同   零“;同样地,”缺乏答案“与”an“不同   没有回答“。

在Java中应用相同的逻辑是完全有效的。

为了使原始类型可以为空,请查看nullable types in C#。将Nullable实现为Java泛型应该很容易。

答案 4 :(得分:1)

我有一个主要的空检查规则永远不会放置null而不是列表或数组。

空列表和数组可以更好地表达它们的真实含义。

答案 5 :(得分:0)

这只是我的意见,但你的例子听起来像一个反模式(作为一个退化的空对象),因为你需要对“null对象”上的方法返回什么进行空检查。如果你根本没有调用那些getter,那么你的例子就是正确的。

使用null对象的想法是您根本不需要执行空检查,因此如果您的getter返回其他null对象,或者方法使用 tell-not-ask <,它可能会起作用/ strong>接近(并且只返回无效)。

答案 6 :(得分:0)

Null非常好,但你应尽量避免使用默认值

例如    应返回空列表而不是null    枚举数据类型应包含UNKNOWN

以上假设使API消费者的生活变得轻松

在你的例子中,我将从animal.getDeathDate返回null,因为我无法想到任何合适的默认值。

我将提供方便的方法animal.isDead返回true / false

对于getFlightSpeed(),我会为你的情况返回0

答案 7 :(得分:0)

空对象模式确实可用于空变量。 在Turtle.getFlightSpeed()的情况下,您可以抽象出SPEED概念(可能是接口或抽象类),并且有一个NULL对象实现“无法飞行”场景。 这将有助于为Turtle类分配默认行为。 在animal.getDeathDate()的情况下返回null似乎很好

答案 8 :(得分:0)

我认为对于animal.getDeathDate(),如果动物还活着则返回null是正确的做事方式。你将永远需要特殊的代码来处理这两种情况:动物活着和动物死亡,如果动物还活着,你就无法返回有用的日期。

对于getFlightSpeed(),事情可能会有所不同。我不确切知道它返回的是什么,但让我们举一个例子想象它只是将速度恢复为m / s

在这种情况下,返回0(或具有相同效果的物体)将非常有意义,因为它确实描述了飞行速度。