我编写了一个从数组中获取数据的函数。该函数的一部分是对数据的验证,它检查密钥是否为空以及数组密钥是否不存在(编辑后我的错误)。该函数如下所示:
public function getData($key = "")
{
if (!empty($key) && !array_key_exists($key, $this->data)) {
throw new ConfigurationException("$key does not exist");
}
return empty($key) ? $this->data : $this->data[$key];
}
应用SRP原则后,将'验证'放入另一个类中,它看起来像这样:
class ConfigurationVerificationHandler
{
public function isPresent($key, array $data)
{
return empty($key) && array_key_exists($key, $data);
}
}
public function getData($key = "")
{
$verificationHandler = new ConfigurationVerificationHandler();
if (!$verificationHandler->isPresent($key, $this->data)) {
throw new ConfigurationException("$key does not exist");
}
return empty($key) ? $this->data : $this->data[$key];
}
从这两个片段中,我期望得到相同的结果,因为我将!
运算符放在isPresent
函数之前,使其检查条件是否为假。
这是怎么来的布尔表达式不一样,不会给出相同的结果?
答案 0 :(得分:2)
您写道“该功能的一部分是对数据的验证,它检查密钥是否为空并且数组密钥是否存在。”,所以您应该这样做:
public function getData($key = "")
{
// Throw exception if key is empty OR array-key does not exist
if (empty($key) || !array_key_exists($key, $this->data)) {
throw new ConfigurationException("$key does not exist");
}
// This won't be executed if $key is empty or does not exist
return $this->data[$key];
}
请注意,由于您没有捕获异常,throw
之后的代码将无法执行!在这里,您在!
之前错过了empty()
。
public function isPresent($key, array $data)
{
return !empty($key) && array_key_exists($key, $data);
}
最终应该是这样的:
public function getData($key = "")
{
$verificationHandler = new ConfigurationVerificationHandler();
if (!$verificationHandler->isPresent($key, $this->data)) {
throw new ConfigurationException("$key does not exist");
}
// $key can't be empty here
return $this->data[$key];
}
阅读PHP Exception handling,因为您混淆了布尔logig,De Morgan's laws。
答案 1 :(得分:1)
!A && !B
与!(A && B)
不同。人们只需看一个变量为真的情况(让我们选择A)而另一个是假的:
!true && !false --> false && true --> false
!(true && false) --> !(false) --> true
但是,!A && !B
等同于!(A || B)
:
!(true || false) --> !(true) --> false
答案 2 :(得分:0)
函数体isPresent()
应为:
public function isPresent($key, array $data)
{
return empty($key) || array_key_exists($key, $data);
}
您从:
开始if (! empty($key) && ! array_key_exists($key, $this->data)) {
,这相当于:
if (! (empty($key) || array_key_exists($key, $this->data))) {
在下一步中,将条件移至isPresent()
方法会导致上面显示的代码。
答案 3 :(得分:-1)
这两行不一样:
if (!empty($key) && !array_key_exists($key, $this->data)) {
return empty($key) && array_key_exists($key, $data);
De Morgan's:
!(P && Q) -> (!P) || (!Q)
由于你的return
版本在调用点被否定,你正在有效地执行!P || !Q版本,与&&
中的if
不完全相同。