太多if-else语句,任何重构方法

时间:2015-11-13 09:34:30

标签: java refactoring

这可以重构吗?或者看起来很好。 (变量名称已更改)

if (cmpScope.equals(GLOBAL)) {
            return true;
        } else if ((cmpScope.equals(X) || cmpScope.equals(Y))
                && cid == pid) {
            return true;
        } else if (cmpScope.equals(Z) && cid != pId) {
            return true;
        } else if (cmpScope.equals(V) && cid == pid) {
            return true;
        } else if (cmpScope.equals(Z) && cid == pid && cSubId != pSubId) {
            return true;
        }
        return false;

5 个答案:

答案 0 :(得分:14)

只需将所有表达式与or-operators组合在一起,因为它们都返回true。

return  ((cmpScope.equals(GLOBAL) ||
         ((cmpScope.equals(X) || cmpScope.equals(Y)) && cid == pid) ||
         (cmpScope.equals(Z) && cid != pId) ||
         (cmpScope.equals(V) && cid == pid) ||
         (cmpScope.equals(Z) && cid == pid && cSubId != pSubId));

答案 1 :(得分:2)

您可以将条件的结果存储在变量中,并在一个语句中处理所有条件。 (虽然我认为在所有情况下都不是更好的解决方案)

boolean trueCond1 = cmpScope.equals(GLOBAL);
boolean trueCond2 = (cmpScope.equals(X) || cmpScope.equals(Y)) && cid == pid;
boolean trueCond3 = cmpScope.equals(Z) && cid != pId;
boolean trueCond4 = cmpScope.equals(V) && cid == pid;
boolean trueCond5 = cmpScope.equals(Z) && cid == pid && cSubId != pSubId;

return (trueCond1 || trueCond2 || trueCond3 || trueCond4 || trueCond5);

答案 2 :(得分:2)

您可以删除所有else,因为每个if子句都返回一个值。

if (cmpScope.equals(GLOBAL)) {
    return true;
}
if ((cmpScope.equals(X) || cmpScope.equals(Y)) && cid == pid) {
    return true;
}
if (cmpScope.equals(Z) && cid != pId) {
    return true;
}
if (cmpScope.equals(V) && cid == pid) {
    return true;
}
if (cmpScope.equals(Z) && cid == pid && cSubId != pSubId) {
    return true;
}
return false;

这是降低代码明显复杂性的最佳技术之一。根据您的特定需求,使用或运算符分组到单个表达式可能是更好的解决方案。此外,cid / pid比较在最后四次测试中很常见,所以这样的事情可能会更好:

if (cmpScope.equals(GLOBAL)) {
    return true;
}
if (cid == pid) {
    if (cmpScope.equals(X) || cmpScope.equals(Y)) {
        return true;
    }
    if (cmpScope.equals(V)) {
        return true;
    }
    if (cmpScope.equals(Z) && cSubId != pSubId) {
        return true;
    }
} else {
    if (cmpScope.equals(Z)) {
        return true;
    }
}
return false;

答案 3 :(得分:2)

我完全支持@ carl-manaster的回应,但我认为我们可以走得更远。

我的方法基于以下原则:

  • 应该没有别的陈述。
  • 应将复杂的逻辑表达式提取到私有方法中以提高可读性。
  • 有一个涵盖所有可能分支的测试套件。这就是人们担心圈复杂性的原因。这就是为什么提取到方法有帮助。

从示例代码中,我们不清楚这个方法到底是什么,所以我选择了一些随机名称,作者应该将其更改为更有效的名称。

我没有测试也没有时间,所以我不能100%确定它会起作用,但经过一系列的更改,我最终得到了以下代码:

function(cid, pid, cSubId, pSubId) {
    return cmpScope.equals(GLOBAL) && isValidSomething() && isValidSomethingElse();
}

提取的方法是:

function isValidSomething() {
    if(cid != pid) {
        return false;
    }
    if (cmpScope.equals(V) || cmpScope.equals(X) || cmpScope.equals(Y)) {
        return true;
    }
    return cmpScope.equals(Z) && cSubId != pSubId;
}

function isValidSomethingElse() {
    return cmpScope.equals(Z) && cid != pId;
}

这只是一个例子,您可以进一步改进它。

同样,这一点的主要目的是让私人方法具有良好的名称,以便你可以阅读它,就像一篇写得很好的散文"。想象一下:

function isMyCarValid() {
    return isHaveWheels() && isHaveFuel() && isHaveDriver();
}

答案 4 :(得分:0)

我假设'return true'只是一个例子?否则,您可以将在一个表达式中返回true的所有语句分组。如果它们实际上是要做不同的事情,那对我来说就好了。 (在某些情况下,可以使用switch语句,而不是在这种情况下,但通常可以很好地知道您可以使用此https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html