2

考虑我有以下豆类:

@Entity
public class Currency {

    private String currency;

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }
}

@Entity
public class SomeEntity  {
    private Currency currency;

    public Currency getCurrency() {
        return currency;
    }

    public void setCurrency(Currency currency) {
        this.currency = currency;
    }
}

我有 SomeEntity 的实例:

SomeEntity entity;

在代码中的某个地方,我想使用一些实体的属性,但实体可能是null,一些实体的属性可能是null,所以我当前的代码实现远非易读:

new ConstantExpression(entity == null ? null : entity.getCurrency() != null ? entity.getCurrency().getId() : null)

有什么方法可以提高这种情况下的代码可读性吗?

更新:我的代码库足够大,所以Null 对象模式实现需要大量修改。此外,我的 bean 使用 JPA 持久化到 db,因此我必须进行额外的编码,例如 Cascade 注释等。

4

4 回答 4

1

由于语言的设计方式,我们永远不会完全摆脱空检查。但是当他们在这里变得太烦人时,这是我喜欢做的一件事。

创建一个“utils”类来为你做空检查。一旦我在 commons-lang 中找到了StringUtils,那真是一个“啊哈”的时刻。想象一下,您有两个字符串需要比较是否相等。

String a;
String b;
// code goes here. a and/or b may or may not be initialized

if (a.equals(b))
{
    // do something
}

正如您痛苦地意识到的那样,上面的代码有出现 NullPointerException 的风险。所以我们必须写:

if (a != null && a.equals(b))
{
    // do something
}

输入 StringUtils。相反,我们写

if (StringUtils.equals(a,b))
{
    // do something
}

如果这太冗长或者我在这段代码中做了很多等价操作,我们可以使用静态导入:

import static org.apache.commons.lang.StringUtils.*;
//...

if (equals(a,b))
{
    // do something
}

瞧 - 即时简洁的代码。这个魔法是如何实现的?没有魔法,只需将空检查放在静态方法中即可。下面是 StringUtils 的实现:

public static boolean equals(CharSequence cs1, CharSequence cs2) {
    if (cs1 == cs2) {
        return true;
    }
    if (cs1 == null || cs2 == null) {
        return false;
    }
    if (cs1 instanceof String && cs2 instanceof String) {
        return cs1.equals(cs2);
    }
    return CharSequenceUtils.regionMatches(cs1, false, 0, cs2, 0, Math.max(cs1.length(), cs2.length()));
}

在您的情况下,请考虑编写一个这样的 utils 类:

public class MyUtils
{
   public static String getCurrencyId(Currency currency)
   {
      if (currency == null)
         return null;
      return currency.getId();
   }

   public static String getCurrencyId(SomeEntity entity)
   {
      if (entity == null)
         return null;
      return getCurrencyId(entity.getCurrency())
   }
}

现在在调用代码中

import static mypackage.MyUtils.*;

new ConstantExpression(getCurrencyId(entity));

是的 - 使用这样的课程是一种妥协。首先必须创建类很烦人,只有你才能决定是否值得付出努力。但是,如果调用代码非常复杂并且空值检查确实难以遵循逻辑,那么从长远来看,拥有一个单独的 utils 类来隐藏空值检查可能会减少工作量。

于 2012-10-11T15:07:55.777 回答
1

您可以使用Null Object Pattern

  • 创建getId()始终返回的 Currency 子类null
  • 有一个此类的单个实例,用于初始化所有currency字段。
  • 现在getCurrency().getId() 是安全的。
  • 如果您愿意,请重复相同的操作SomeEntity
于 2012-10-11T08:11:11.710 回答
0

你可以简单地实现一个装饰器,它接受一个实体并简单地提供方便的访问方法。

于 2012-10-11T08:04:31.370 回答
0

虽然我不喜欢使用它们,但有些人使用充满“Null”值和对象的“Null”对象而不是使用null.

于 2012-10-11T08:06:48.107 回答