一个合适的模式,而不是返回空值

时间:2012-12-27 10:02:28

标签: java design-patterns optimization

在这里使用什么样的好模式?

我不想返回空值,这感觉不对。

另一件事是,如果我想返回导致它为null的原因怎么办?如果调用者知道它为什么是null,它可以做一些额外的事情,所以我希望调用者知道它并以这种方式行事

Public CustomerDetails getCustomerDetails(){
   if(noCustomer){    
     ..log..etc..
     return null;
   }

   if(some other bad weird condition){    
     ..log..etc..
     return null;
   }

   CustomerDetails details= getCustomerDetailsFromSomewhere();

   if (details!=null){
      return details;
   }
   else {
     ..log..etc..
     return null;
   }

}

7 个答案:

答案 0 :(得分:8)

我认为你有3个主要选择:

  • 如果null是有效状态,我认为返回null
  • 没有问题
  • 如果null是无效状态,则应抛出异常
  • 或使用Null object pattern

如果您使用的是Google Guava libraries,还可以使用Optional课程。

答案 1 :(得分:3)

Java中更自然的方法是在错误条件下抛出异常。

public CustomerDetails getCustomerDetails(){
   if(noCustomer){    
     ..log..etc..
     throw new NoSuchCustomer(customerName);
   }

   if(some other bad weird condition){    
     ..log..etc..
     throw new IllegalStateException("some other bad weird condition occurred");
   }

   CustomerDetails details= getCustomerDetailsFromSomewhere();

   if (details==null)
      throw new IllegalStateException("Failed to get customer details for "+ customerName);

   return details;
}

方法getCustomerDetailsFromSomewhere()可能会抛出异常而不是返回null。

答案 2 :(得分:1)

尝试Guava的可选项。请参阅有关避免null的文章:http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained

答案 3 :(得分:1)

使用Google Guava Optional

这会有所帮助。

  

程序员使用null的许多情况都是表示某种情况   缺席:可能存在价值的地方   没有,或者找不到一个。例如,Map.get返回null   当没有找到密钥的值时。

     

可选是用a替换可空的T引用的一种方法   非空值。 Optional可以包含非null T引用   (在这种情况下,我们说引用是“存在”),或者它可能包含   什么都没有(在这种情况下我们说引用是“缺席”)。永远不会   说“包含空”。

Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5

答案 4 :(得分:1)

你可以试试;

CustomerDetails details = setDetailsToEmpty();

或某些等价物。

您仍需检查空客户信息或空客户信息。

答案 5 :(得分:1)

如果你真的不想让null创建一个特殊的CustomerDetails对象

...
        public static final CustomerDetails EMPTY_CUSTOMER_DETAILS = new CustomerDetails();
...    
        public CustomerDetails getCustomerDetails(){
            ...
            if (details!=null){
                return details;
            }
            ...
            return EMPTY_CUSTOMER_DETAILS;

答案 6 :(得分:1)

如果你的意思是null没有解释它的状态,你可以用另一个可以提供更多细节的类来包装CustomerDetails。例如:

class Feedback()
{
    private CustomerDetails result;
    private int status;

    public static final int STATUS_OK = 0;
    public static final int STATUS_NULL = 1;
    public static final int STATUS_NO_CUSTOMER = 2;
    public static final int STATUS_BAD_CONDITION = 3;

    public Feedback(CustomerDetails result, int status)
    {
        this.result = result;
        this.status= status;
    }

    public CustomerDetails getResult(){return result;}
    public int getStatus(){return status;}
}

并使用以下方法更改您的方法:

Public Feedback getCustomerDetails()
{
   if(noCustomer)
   {
       ..log..etc..
       return new Feedback(null, Feeback.STATUS_NO_CUSTOMER);
   }

   if(some other bad weird condition)
   {
       ..log..etc..
       return new Feedback(null, Feeback.STATUS_BAD_CONDITION);
   }

   CustomerDetails details = getCustomerDetailsFromSomewhere();

   if(details != null)
   {
        return new Feedback(details, Feeback.STATUS_OK);
   }
   else
   {
       ..log..etc..
       return new Feedback(null, Feeback.STATUS_NULL);
   }
}

然后您可以按feedback.getStatus()获取状态。