处理多个“否则”语句的最佳实践

时间:2019-09-03 14:29:53

标签: javascript typescript if-statement switch-statement

如果没有将多个条件案例绑定到一个变量,那么处理这些案例的最佳实践是什么?

例如,我们可以使用else if语句:

if (a && b > 10) {
    ...
} else if (a && b < 5) {
    ...
} else if (!a && c === 'test') {
    ....
} else if (!a && c === 'test2') {
    ...
} else {
    ...
}

请注意,我们不能在此处使用简单的开关。我们也不能将map与选项一起使用。 但是我们可以使用switch(true)使其更具可读性:

switch(true) {
    case (a && b > 10):
        ...
        break;
    case (a && b < 5):
        ...
        break;
    case (!a && c === 'test'):
        ...
        break;
    case (!a && c === 'test2'):
        ...
        break;
    default:
        ...
}

或者那样:

switch(true) {
    case isValid():
        ...
        break;
    case hasMeasurements():
        ...
        break;
    case isHighDensity():
        ...
        break;
    case isObsolete():
        ...
        break;
    default:
        ...
}

我已经阅读了几本有关switch(true)使用情况的帖子。如下所示:javascript switch(true)

有人说这没错。其他人建议根本不要使用它。

在没有一个变量的情况下,针对多种条件的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:1)

如果if语句/切换逻辑会导致测试和Cyclomatic Complexity出现问题,则为

普遍接受的解决方案是将逻辑以及与其关联的功能存储在列表/字典中(不是一个完美的例子):

public class LogicalFunc
{
  Logic: () => boolean;
  Func: () => void;
}

const logicalFunctions: LogicalFunc[] = [
  new LogicalFunc {
    Logic: (a: number, b: number) => (a && b) > 10,
    Func: () => someOtherFunc(),
  }
];

function myFunction(a: number, b: number) {

  const logicalFunc = logicalFunctions.find(lf => lf.Logic(a,b));
  if (logicalFunc) {
    logicalFunc.Func();
  } else {
    // some default
  }
}

function someOtherFunc() {}

现在,您的逻辑测试与方法是分开的,这意味着您可以独立于myFunction测试列表。您也可以覆盖列表以测试myFunction仅有的两种可能的结果,即找到了一项还是没有找到一项。肯定的覆盖列表为:

  new LogicalFunc {
    Logic: (a: number, b: number) => true,
    Func: () => void(),
  }

,否定项将有一个空列表。

Eliminating Cylclomatic Complexity by replacing switch/case with a method or a Dictionary> (c#)

Refactoring Switch Statements To Reduce Cyclomatic Complexity (c#)

Cyclomatic complexity refactoring tips for javascript developers

No ifs…alternatives to statement branching in JavaScript

答案 1 :(得分:0)

我确定您知道,这里确实没有正确的答案。更好的可读性是最好的选择。我认为您会发现其他开发人员在阅读if,else链而不是布尔型switch语句(会有时间和地点)时会更加快乐。给定您的示例,我将尝试将其分解为更笼统的语句,然后从中进行更深入的研究。例如,而不是这样:

if (a && b > 10) {
    ...
} else if (a && b < 5) {
    ...
} else if (!a && c === 'test') {
    ...
} else if (!a && c === 'test2') {
    ...
} else {
    ...
}

也许是这样

if (a) {
    if (b > 10) {
        ...
    } else if (b < 5) {
        ...
    }
} else {
    if (c === 'test') {
        ...
    } else if (c === 'test2') {
        ...
    }
}

在您的情况下,由于此解决方案无法容纳链中的最终else语句,因此无法正常工作,但我的观点是,在大多数情况下,具有复杂逻辑的if,else链具有细长的布尔语句并尽可能线性。在我看来,除非确实需要,否则不需要涉及switch语句。