我有一个通过工厂构建的对象,其中包含从url读取的参数。
从这个对象,我可以得到语言参数
如果没有设置,$ language = $ my_parameters->使用getLanguage();
$ language为NULL。
$ language也可能无效($ language-> isValid()返回false)。
因此,要构建我的页面,我需要一些参数。
该页面也是通过工厂建造的。然后我知道我需要构建它的参数。如果它遗漏了参数,我会根据询问的页面使用有效的默认值构建它们。
此时,进入页面工厂,如果一个参数无效,我会抛出异常。
我的页面对象包含一个需要语言参数的正文对象。我知道当我构建我的身体对象时,我的参数是有效的。
进入我的身体对象,我检索语言
$ language = $ 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对象中使用。
身体对象可以在工厂外建造。 谁知道......
在这种情况下验证是否正确?
最佳做法是什么?
答案 0 :(得分:3)
Here is the case for not checking for null在Google测试博客最近发表的一篇博文中。
这个论点是它妨碍了编写清晰,简单的单元测试,因为你实际上不能伪造那些无关紧要的部分,因为你的异常/断言会被抛出。
作者(MiškoHevery)确实对评论有资格说,如果它是一个外部API,它仍然值得检查错误情况。
答案 1 :(得分:1)
我对你的域名知之甚少,但在一般情况下,我喜欢在整个地方断言(而不是null),因为通常如果我最终在某个地方找到一个空对象,那就是一个bug。
优先选择通常甚至不能为null的引用类型也是一种好习惯。
答案 2 :(得分:1)
我来自一所非常古老的C编程学校;所以我的事情是,未使用或已经free()的变量应始终为NULL。这只是我的观点。
编辑:在此基础上,您应该在使用之前检查变量是否为NULL。如果变量为NULL且不应该是,则应记录错误。崩溃不应成为一种特征。
答案 3 :(得分:1)
通过将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。 / p>
答案 4 :(得分:1)
从 - > getLanguage()抛出异常。
对我来说,应该自动抛出异常。你在做什么似乎是错误代码检查和异常抛出的混合。