【问题标题】:Should I always verify if an object is NULL?我是否应该始终验证对象是否为 NULL?
【发布时间】:2009-02-12 03:18:45
【问题描述】:

我有一个通过工厂构建的对象,其中包含从 url 读取的参数。

从这个对象,我可以得到语言参数

$语言= $my_parameters->getLanguage();

$language 如果未设置,则为 NULL。

$language 也可能无效($language->isValid() 返回 false)。

所以,要构建我的页面,我需要一些参数。

该页面也是通过工厂构建的。然后我知道构建它需要哪些参数。如果它错过了参数,我会根据所要求的页面使用有效的默认值来构建它们。

此时,进入页面工厂,如果a有无效参数,我抛出异常。

我的页面对象包含一个需要语言参数的正文对象。我知道我的参数在我构建我的 body 对象时是有效的。

在我的身体对象中,我检索语言

$语言 = $my_parameters->getLanguage();

此时,$language ** 必须 ** 有效。 所以我再次验证

$language = $my_parameters->getLanguage();
if( is_null( $language ) or !$language->isValid() ) {
   throw new Exception( 'Language must be valid.' );
}

如果我需要 4 个参数,我有 4 个 ifs 来验证对象是否不为 NULL 且不无效。

我这样做是因为 方法是公开的 其中 $language 在 body 对象中使用。

并且body对象可能是在工厂之外构建的。 谁知道...

这种情况下验证是否正确?

这方面的最佳实践是什么?

【问题讨论】:

    标签: php oop


    【解决方案1】:

    Here is the case for not checking for null 在 Google 测试博客最近的一篇博文中。

    争论是它妨碍了编写清晰、简单的单元测试,因为你实际上不能伪造无关紧要的部分,因为你的异常/断言会被抛出。

    作者 (Miško Hevery) 确实限定了评论,说如果它是一个外部 API,它可能仍然值得检查错误情况。

    【讨论】:

    • 我喜欢这个网站。现在我实际上还没有测试。但我渴望它。 :-)
    【解决方案2】:

    我对您的域知之甚少,但在一般情况下,我喜欢在所有地方都断言(非空),因为通常如果我在某处得到一个空对象,这是一个错误。

    最好选择通常甚至不能为空的引用类型。

    【讨论】:

      【解决方案3】:

      我来自一个非常古老的 C 编程学校;所以我的事情是那些没有被使用或已经 free()'d 的变量应该始终为 NULL。不过这只是我的看法。

      编辑:在此基础上,您应该始终检查变量是否为 NULL,然后再使用它。如果变量为 NULL 并且不应该是,那么您应该记录一个错误。崩溃不应该是一项功能。

      【讨论】:

      • 在 Java 中,每次获取对象时检查 NULL 会导致代码非常冗长。我宁愿让它崩溃并修复它。
      【解决方案4】:

      您可以通过将 getLanguage() 拆分为两种方法来简化自己的工作:

      function getLanguageIfValid() {
        // this method return a Language object, but only if it can be created
        // correctly and the isValid() method returns TRUE. If the Language object
        // can't be created correctly, then it will return null instead.
      }
      
      function getLanguageMustBeValid() {
          // this method will always return an instance of Language, or else
          // an exception will be thrown
          if($return = $this->getLanguageIfValid())
              return $return;
          throw new Exception("Couldn't get Language object");
      }
      

      一旦你这样做了,在有理由说可能没有正确创建语言项目的地方,你使用第一种方法:

      // we may or may not be able to get our Language object here
      if($language = $my_parameters->getLanguageIfValid())
          do_stuff($language);
      

      如果您确定应该创建语言对象,请使用第二种方法,该方法将为您抛出异常。

      // we know the Language object is created at this point
      $language = $my_parameters->getLanguageMustBeValid();
      do_stuff($language);
      

      所以您的问题的答案是 - 只要您可以从我们保证不返回 null 的函数中获取对象,您就不必验证对象不为 null。

      【讨论】:

        【解决方案5】:

        从 ->getLanguage() 抛出你的异常。

        对我来说,应该自动抛出异常。您所做的似乎是错误代码检查和异常抛出的混合体。

        【讨论】:

          猜你喜欢
          • 2013-06-20
          • 2015-01-30
          • 2011-01-22
          • 2011-02-27
          • 1970-01-01
          • 1970-01-01
          • 2016-02-16
          • 1970-01-01
          相关资源
          最近更新 更多