You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何实现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:动态操作数组(适合多开关的复杂场景)

如果有多个可选操作(比如同时有useFilteruseMap两个开关),可以用数组动态收集要执行的操作,再统一执行:

// 初始化操作数组
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

火山引擎 最新活动