如何实现Array方法的可选链式调用?求简洁SOLID实现方案
嘿,这个需求我太熟了!想要让数组的链式操作支持可选步骤,同时还要符合SOLID原则,这里有几个既简洁又优雅的方案,你可以根据场景选:
方案1:短路求值链式调用(适合简单单开关场景)
这种方式利用JS的短路求值特性,直接在链式调用里嵌入条件判断,保持代码的紧凑性:
const result = (useFilter ? data.filter(isDog) : data).map(dogYears).reduce(sum);
为什么符合SOLID?
- 每个数组方法(
filter/map/reduce)都保持了单一职责,只做自己的事 - 逻辑清晰,修改
useFilter的判断逻辑或者替换某个操作时,不会影响其他步骤
方案2:管道函数模式(最符合SOLID原则,推荐用于复杂扩展场景)
把每个操作拆成独立的纯函数,再用一个管道函数把它们组合起来,完美契合开闭原则(对扩展开放,对修改关闭):
首先定义通用的管道函数:
// 管道函数:接收一系列函数,依次执行并传递结果 const pipe = (...fns) => initialValue => fns.reduce((acc, fn) => fn(acc), initialValue);
然后把每个操作封装成独立函数,包括可选的过滤操作:
// 可选过滤:根据条件决定是否执行filter const optionalFilter = (condition, filterFn) => arr => condition ? arr.filter(filterFn) : arr; // 固定的狗年转换操作 const mapToDogYears = arr => arr.map(dogYears); // 固定的求和操作 const sumAges = arr => arr.reduce(sum);
最后组合使用:
// 组装成完整的计算流程 const calculateDogAges = pipe( optionalFilter(useFilter, isDog), mapToDogYears, sumAges ); // 执行计算 const result = calculateDogAges(data);
为什么符合SOLID?
- 单一职责:每个函数只做一件事(过滤、转狗年、求和)
- 开闭原则:要加新的可选操作(比如可选跳过map),只需要新增一个
optionalMap函数,完全不用修改现有代码 - 依赖倒置:管道函数不依赖具体操作,只依赖函数的输入输出约定,扩展性极强
方案3:动态操作数组(适合多开关的复杂场景)
如果有多个可选操作(比如同时有useFilter、useMap两个开关),可以用数组动态收集要执行的操作,再统一执行:
// 初始化操作数组 const operations = []; // 根据开关添加操作 if (useFilter) operations.push(arr => arr.filter(isDog)); operations.push(arr => arr.map(dogYears)); // 必选操作直接加 operations.push(arr => arr.reduce(sum)); // 依次执行所有操作 const result = operations.reduce((acc, fn) => fn(acc), data);
优势
- 灵活度拉满,新增或移除操作只需修改数组的push逻辑
- 每个操作都是独立的纯函数,符合单一职责,调试和维护都很方便
内容的提问来源于stack exchange,提问作者Coyolero




