我写的函数看起来像这样:
bool IsDry(bool isRaining, bool isWithUmbrella) {
if (isRaining) {
if (isWithUmbrella)
return true;
else
return false;
}
else
return true;
}
我需要检查一下,如果正在下雨,那么这个人需要带伞以保持干爽(不要笑,这只是一个例子,我们的实际业务规则比这更严重)。
我怎么能重构这个,因为现在它看起来很笨拙。
谢谢你的帮助,伙计们! =)
答案 0 :(得分:69)
您尝试执行的业务规则似乎是:
P IMPLIES Q
这在逻辑上等同于:
(NOT P) OR Q
因此,您可以简单地写:
bool IsDry(bool isRaining, bool isWithUmbrella) {
return !isRaining || isWithUmbrella;
}
根据谓词的不同,首先要考虑它的否定也可能更简单。
NOT (P IMPLIES Q)
我们现在用上面的身份代替:
NOT ((NOT P) OR Q)
现在我们可以申请DeMorgan's Law:
P AND (NOT Q)
由于这是否定,我们必须否定这一点,以回到正面。双重否定一开始可能看起来令人困惑,但回到这个例子,我们有:
bool IsDry(bool isRaining, bool isWithUmbrella) {
bool isWet = (isRaining && !isWithUmbrella);
return !isWet;
}
以下是常见boolean
表达式重写的一些示例:
BEFORE | AFTER
________________________________________|________________________________________
|
if (condition == true) ... | if (condition) ...
________________________________________|________________________________________
|
if (condition == false) ... | if (!condition) ...
________________________________________|________________________________________
|
if (condition) { | return condition;
return true; |
} else { |
return false; |
} |
________________________________________|________________________________________
|
if (condition1) { | return (condition1 && condition2
if (condition2) { | && condition3);
if (condition3) { |
return true; |
} else { |
return false; |
} |
} else { |
return false; |
} |
} else { |
return false; |
} |
________________________________________|________________________________________
|
return (condition1 && !condition2) || | return condition1 != condition2;
(condition2 && !condition1); | // or condition1 ^ condition2;
请注意,C#中的预定义^
是exclusive-or operator,即使对于整数类型(即它不是取幂运算符)。预定义的&&
和||
是执行“短路”评估的conditional logical operators。
答案 1 :(得分:11)
bool IsDry(bool isRaining, bool isWithUmbrella)
{
return (!isRaining || isWithUmbrella);
}
答案 2 :(得分:8)
bool IsDry(bool isRaining, bool isWithUmbrella)
{
return !isRaining || isWithUmbrella;
}
答案 3 :(得分:5)
这是一个真值表:
isRaining isWithUmbrella isWet isDry
true true false true
true false true false
false true false true
false false false true
有一个答案可能是:
var isWet = isRaining && !isWithUmbrella;
return !isWet;
答案 4 :(得分:5)
我通常采用的方法是不断改进。例如首先消除内在的if-else:
bool IsDry(bool isRaining, bool isWithUmbrella) {
if (isRaining)
return isWithUmbrella;
else
return true;
}
然后崩溃if
bool IsDry(bool isRaining, bool isWithUmbrella) {
return isRaining ? isWithUmbrella : true;
}
答案 5 :(得分:3)
我该如何重构
进行单元测试。
严重。有两个布尔输入,因此您只需要四个单元测试即可完全覆盖此方法。
然后,在已经存在完整分支覆盖的情况下,您可以直接使用实现。尝试一些看起来正确的东西(我觉得在这种情况下写一个真值表非常有帮助),测试会告诉你是否有错误的细节。
作为进一步的好处,您可以永远保持测试,作为方法实际执行的文档。如果你选择一个聪明的实现,如花哨的布尔表达式,这是特别有用的 - 如果你试图跟随流程,你可以看看测试,看看,“哦,我明白了 - 如果我通过这个,这个,我明白了。“
答案 6 :(得分:1)
bool IsDry(bool isRaining, bool isWithUmbrella) {
return isRaining ? isWithUmbrella : true;
}
答案 7 :(得分:1)
只需点击六次ReSharper,您就可以将代码简化为一行。
前三次点击将变形
if (isWithUmbrella)
return true;
else
return false;
到
return isWithUmbrella;
接下来的三次点击更改
if (isRaining)
{
return isWithUmbrella;
}
else
return true;
到
return !isRaining || isWithUmbrella;
瞧,你已经完成了。
答案 8 :(得分:1)
首先从“else return ...;”中删除“else”陈述,所以你得到:
if (isRaining) {
if (isWithUmbrella)
return true;
return false;
}
return true;
有一点逻辑工作..
if (isRaining) {
// return (isWithUmbrella) ?
// true :
// false;
return isWithUmbrella;
}
return true;
然后,您可以快速将其置于一个简单的返回语句中......
//return (isRaining) ? isWithUmbrella : true;
//return (!isRaining) ? true : isWithUmbrella;
return (!isRaining) || isWithUmbrella;
答案 9 :(得分:0)
非常明显
bool IsNotRaining {return isWithUmbrella}
: - )