javascript - 用谓词列表替换条件列表(if/switch/三元运算符)有哪些优点和缺点?

标签 javascript conditional-statements predicate

最近我遇到了一个学派,主张用其他东西(多态性、策略、访问者等)替换条件语句(if/switch/三元运算符,下同)。

由于我想通过尝试新方法来学习,因此我修改了一些 Javascript 代码并立即找到了相关案例,基本上是以下 ifs 列表(本质上与 switch/嵌套三元运算符):

function checkResult(input) {
    if (isCond1Met(input)) return result1;
    if (isCond2Met(input)) return result2;
    if (isCond3Met(input)) return result3;
    // More conditionals here...
    if (isCondNMet(input)) return resultN;
    return defaultResult;
};

就在我想出尝试使用谓词列表后不久。

假设 checkResult 总是返回一个字符串(适用于我的具体情况),上面的 if 列表可以替换为谓词列表(它使用箭头函数并查找哪些是 ES6+ 功能):

var resultConds = {
    result1: isCond1Met,
    result2: isCond2Met,
    result3: isCond3Met,
    // More mappings here...
    resultN: isCondNMet
};
var results = Object.keys(resultConds);

function checkResult(input) {
    return results.find(result => resultConds[result](input)) || defaultResult;
};

(旁注:checkResult 是否应将 resultConds 和 defaultResult 作为参数应该是一个相对较小的问题,下同)

如果上述假设不成立,谓词列表可以改为:

var conds = [
    isCond1Met,
    isCond2Met,
    isCond3Met,
    // More predicates here...
    isCondNMet
];
var results = [
    result1,
    result2,
    result3,
    // More results here...
    resultN
];

function checkResult(input) {
    return results[conds.findIndex(cond => cond(input))] || defaultResult;
};

更大的重构可能是这样的:

var condResults = {
    cond1: result1,
    cond2: result2,
    cond3: result3,
    // More mappings here...
    condN: resultN,
};
var conds = Object.keys(condResults);

function checkResult(input) {
    return condResults[conds.find(cond => isCondMet[cond](input))] || defaultResult;
};

我想问一下用谓词列表替换条件列表的优点和缺点(最好有相关经验和解释),至少在这种情况下(例如:输入验证检查根据条件列表返回非 bool 结果)?

例如,哪种方法通常可能会更好:

  • 可测试性(如单元测试)
  • 可扩展性(当条件/谓词越来越多时)
  • 可读性(对于那些熟悉这两种方法以确保足够公平的比较的人来说)
  • 可用性/可重用性(避免/减少代码重复)
  • 灵 active (例如,当用于验证输入的内部较低级别逻辑发生巨大变化,同时保留相同的外部较高级别行为时)
  • 内存占用/时间性能(特定于 Javascript)
  • 等等

此外,如果您认为谓词列表方法可以改进,请随时演示该改进方法的优缺点。

编辑:正如 @Bergi 提到的 Javascript 对象是无序的,ES6+ map 可能是更好的选择:)

最佳答案

一般来说,将业务逻辑(如这些谓词)放在单独的对象中总是可以提高可测试性、可扩展性、可读性、可维护性和可重用性。这来自于这种 OOP 设计固有的模块化,并允许您将这些谓词保存在中央存储中,并在它们上应用您想要的任何业务过程,从而保持独立于代码库。本质上,您将这些条件视为数据。您甚至可以动态选择它们,将它们转换为您的喜好,并在抽象层上使用它们。

当您需要达到一定的长度以用通用方法替换简单的简短条件时,可读性可能会受到影响,但如果您有很多谓词,那么它会带来很好的返回。

添加/更改/删除谓词的灵 active 提高了很多,但是选择不同架构(如何应用哪种谓词)的灵 active 会变差 - 你不能只在一个小位置更改代码,你需要触摸每个使用谓词的位置。

内存和性能占用也会更大,但还不够重要。

关于可扩展性,只有选择好的架构才有效。需要以线性方式应用的规则列表在一定大小时可能不再起作用。

关于javascript - 用谓词列表替换条件列表(if/switch/三元运算符)有哪些优点和缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42948150/

相关文章:

javascript - 是否可以在 IFrame 内容在同一域下运行的 IFrame 中沙箱 JavaScript?

javascript - 获取 "children"的数组索引不允许进一步使用 jQuery

if-statement - SICP lisp 'if' 条件表达式解释

c - 去掉程序中的 break 语句

sql-server - SQL Server - 同一列上的谓词和查找谓词

javascript - 当我完成导入数据提取后,如何重定向到会计仪表板?

javascript - 如何获取 Ember 项目中元素的顶部偏移量?

javascript - 检查angularjs中的条件

java - 根据 Map 输入从 Collection<Objects> 中提取对象

sql - 如何在不使用and子句的情况下在Sql查询中使用Between子句