处理未绑定(bind)到一个变量的多个条件情况的最佳实践是什么?
例如,我们可以使用 else if
声明:
if (a && b > 10) {
...
} else if (a && b < 5) {
...
} else if (!a && c === 'test') {
....
} else if (!a && c === 'test2') {
...
} else {
...
}
这只是示例,因此不要尝试通过重新组合逻辑来简化它。请注意,我们不能在这里使用简单的 switch。我们也不能将 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:
...
}
它绝对合法,并且受到许多作者的推荐。但另一方面,许多开发人员不喜欢它,因为 true 语句不是变量而是常量。
我读过一些关于 switch(true)
的帖子用法。如下:javascript switch(true)
在没有单一变量的情况下,针对这种多种情况的最佳解决方案是什么?
解决方案: 我最终得到了Erik Philips答案的简化版本。谢谢埃里克!
let descriptionByType: {description: string, check: check: () => Boolean}[] = [
{ description: 'result 1', check: () => a && b > 10 },
{ description: 'result 2', check: () => a && b < 5 },
{ description: 'result 3', check: () => !a && c === 'test' },
{ description: 'result 4', check: () => !a && c === 'test2' },
{ description: 'default result', check: () => true },
];
return descriptionByType.find(x => x.check()).description;
非常清晰和灵活。
最佳答案
太多的 if 语句/switch 逻辑可能会导致测试和 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(),
}
负片将有一个空列表。
Refactoring Switch Statements To Reduce Cyclomatic Complexity (c#)
Cyclomatic complexity refactoring tips for javascript developers
关于javascript - 处理多个 "else if"语句。降低圈复杂度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57773801/