我的逻辑情况最好被描述为试图赢得任务的两个“团队”。这项任务的结果可能是一个胜利者,一个平局(平局),或者没有胜利者(僵局)。
目前,我正在使用嵌套的if / else语句,如下所示:
// using PHP, but the concept seems language agnostic.
if ($team_a->win()) {
if ($team_b->win()) {
// this is a draw
} else {
// team_a is the winner
}
} else {
if ($team_b->win()) {
// team_b is the winner
} else {
// This is a stalemate, no winner.
}
}
这似乎很像意大利面和重复。我可以使用更合乎逻辑的DRY模式吗?
答案 0 :(得分:6)
另一种方式是win(a)&&赢(b)然后抽奖,否则如果赢(a),否则赢(b)。
或者:
if win(a) and win(b) then
// Draw
else if win(a) then
// a wins
else if win(b) then
// b wins
else
// Stalemate
答案 1 :(得分:4)
我认为它不会比你现在做的好得多。
另一种方法是使用切换表达式:
switch (($team_a->win() << 1) + $team_b->win()) {
case 3:
// this is a draw
case 2:
// team_a is the winner
case 1:
// team_b is the winner
case 0:
// This is a stalemate, no winner.
}
然而,虽然它更干,但我认为这不会提高可读性。请注意,在某些语言而不是$team_x->win()
中,您需要编写($team_x->win() ? 1 : 0)
。
答案 2 :(得分:3)
if($TeamA->win() && $TeamB->win()){
// Tie
}else if($TeamA->win()){
// Team A wins
}else if($TeamB->win()){
// Team B wins
}else{
// No winner
}
此外,根据你的win()方法的作用,在if...else
之外检查一次可能更有效,所以它只运行一次检查:
$team_a = $TeamA->win();
$team_b = $TeamB->win();
if($team_a && $team_b){
// Tie
}else if($team_a){
// Team A wins
}else if($team_b){
// Team B wins
}else{
// No winner
}
答案 3 :(得分:2)
简化嵌套语句:
if($team_a->win() and $team_b->win())
{
// Draw
}
elseif($team_a->win())
}
// Team A Won
}
elseif($team_b->win())
}
// Team B Won
}
else
{
// No Winner
}
答案 4 :(得分:1)
这是@Mark Byers版本的扩展版本,旨在使其背后的逻辑更加清晰。
$result_code = 0;
if ($team_a->win()) $result_code += 1;
if ($team_b->win()) $result_code += 2;
switch ($result_code) {
case 0:
//stalemate
case 1:
//a wins
case 2:
//b wins
case 3:
//draw
}
这是一个非常好的程序,这个数字不会在任何组合中得出相同的结果,我想你将来会有很多场合使用它。它与* nix权限中使用的逻辑相同,可以使用&lt; 2个操作数:如果它们是3个,你可以使用4,2和1等等。
在这种特殊情况下,它也加快了处理速度,因为你只需要调用一次团队对象的方法。
答案 5 :(得分:1)
当这种类型的逻辑被封装在一个方法中时,早期返回可能比{} else阻塞更可读:
function game_end($a,$b) {
if ($team_a->win() && $team_b->win()) {
// this is a draw
return;
}
if ($team_a->win()) {
// team_a is the winner
return ;
}
if ($team_b->win()) {
// team_b is the winner
return ;
}
// This is a stalemate, no winner.
}
答案 6 :(得分:0)
你不能使用更直接的陈述......
类似
IF(a AND b) THEN {a,b}
ELSE If (a AND NOT(b)) THEN {a}
ELSE If (not(a) AND NOT(b)) THEN { }
ELSE {b}
与其他一些帖子相比,这是非常易读但不是最简洁的。
答案 7 :(得分:0)
如果您要分成两组,请考虑:
if (win(a) != win(b)) {
// common code when there's a winner, regardless of who
if (win(a)) {
// code specific to a winning
} else {
// code specific to b winning
}
} else {
// common code for a non-result
if (win(a)) {
// code specific to a draw
} else {
// code specific to a stalemate
}
}
如果你处于两个位置之一中有一些共同代码的最佳位置,可能会有用,但是抽象到一个函数并且从四个块中的两个块调用它是不值得的,或者是不可能的。 if/else if
和switch/case
答案。
答案 8 :(得分:0)
就像我在评论中所说,我认为胜利条件及其决定是在错误的地方。 (例如快速电子代码)有什么问题:
if ($team_a->score() > $team_b->score()) return 'Team A wins!';
else if ($team_a->score() < $team_b->score()) return 'Team B wins!';
else return 'It's a tie!';
(语法可能有误,但你明白了)
重构比尝试自己创建问题的解决方案更好。
答案 9 :(得分:0)
寻找干燥模式的问题在这里是错误的,因为问题既不复杂也不足以保证重构/简化,并且其圈复杂性太低而无法担心 spaghettization 。
这是一个算法问题,准确的布尔代数...... 和一个非常简单的启动。您必须进行3次比较,至少4个分支做出决定。
IF (A ^ B) -> draw
ELSE (!A ^ !B) -> no win
ELSE A -> a wins
ELSE -> b wins
用更少的东西做逻辑是不可能的。这里唯一的冗余是$team_b->win()
的重新计算(简单地计算两个团队的胜利,并在if语句之前将它们放在本地变量中)。