空对象模式与新对象

时间:2015-11-18 09:27:21

标签: java design-patterns

我知道Null Object模式可以让我们摆脱对null的重复检查。在我的项目中有很多代码看起来像这样(当然它显着简化,只是为了表明这个想法):

public User getUserById(Long id) {
   ... // create db query
   return (User) query.getSingleResult();
}

然后我们

public String isUserAdmin(Long id){
   User user = getUserById(id);
   if(user != null) {
      if(user.isAdmin()) {
         return "success";
      } else {
         return "forbidden";
      }
   }
}

现在不是检查用户是否为空,而是检查内部的getUserById方法,如果DB的结果为null,如果是,我们可以返回NullUser对象。

但我的问题是 - 我们需要做什么Null Object模式(在这种情况下是NullUser对象)?我们不能只返回新的User()吗?

3 个答案:

答案 0 :(得分:1)

我们可以使用;

  • a null并检查null如果您检查不到,则会收到错误并显示堆栈跟踪。
  • 假设我们不会忘记这样做,NullUser可以检查空对象,或者
  • 我们每次都可以返回一个new User()并检查一个空用户,虽然这可能比使用NullUser更容易出错并且容易混淆。
  • 您可以使用Optional<User>仍然需要执行检查,但它有一些方便的辅助方法。

顺便说一下,你应该坚持一个标准,如果你发现自己编写这样的代码,你就做错了。

Optional<User> u = ...
if (u != null && u.isPresent() && !u.get().isNull() && !u.get().isEmpty())
    // you have gone mad!

答案 1 :(得分:1)

NullObject编程模式用于当你的代码需要一个有效的对象但是你无法传递一个时,一个null对象基本上实现原始对象的所有方法和值并继承它但是如果调用方法则什么都不做,这样你的代码永远不会出错但是如果你给一个空对象代替普通对象它不会出错但也不会做任何事情

例如:

public class User {
    private string name;
    public string GetName() {
        return name;
    }
}

public class NullUser : User {
    public override string GetName() {
        return "";
    }
}

在这里你可以传递一个NullUser对象而不是一个用户对象,以确保没有任何反应,但这种编程模式只在某些情况下有用

答案 2 :(得分:0)

  

我们不能只返回新的User()吗?

  • null用户通常表示无法找到用户。
  • 可以很容易地解释new User(),因为找到了一些用户。

因此,返回新实例可能是正确的解决方案,但取决于您的域。对于e.x.如果你有一个配置,发送一个新实例而不是null可能是完全正常的。

空对象模式

与所有“设计模式”一样,正确的答案取决于它。 这取决于设计模式设计解决的问题是否也是您的问题陈述。从经验我可以看出,如果你的意图是忽略“空”检查,那么空对象模式可能会导致比它解决的问题更多的问题。

相关问题