最近我遇到了一个学派,主张用其他东西(多态性、策略、访问者等)替换条件语句(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/