首页 > 解决方案 > 将两个相似的功能合二为一

问题描述

我有两个非常相似的功能,我想结合一些小的差异:

private filterByOperationType() {
    let operationBuffer: IProductOperation[] = [];
    if (this.filterConditions[0].selected.length > 0) {
      operationBuffer = this.operations.filter(({ operationDetails }) => {
          let operationType = false;
          for (const details of this.filterConditions) {
            if (details.name === 'Type') {
              const parsedGroup = details.selected[0].text;
              if (parsedGroup === operationDetails) {
                operationType = true;
              }
            }
          }
          return operationType;
        });
      }
    return operationBuffer;
  }

  /** Filter the operations by function group when dropdown is used */
  private filterByFunctionGroup() {
    const filteredData = this.operations.filter(({ functionDetails }) => {
      let groupDescriptionMatch = false;
      for (const details of this.filterConditions) {
        if (!details.selected[0]) {
          return;
        }
        if (details.name === 'Function group') {
          const parsedGroup = details.selected[0].text.match(/[a-zA-Z]+/g);
          if (parsedGroup?.join(' ') === functionDetails) {
            groupDescriptionMatch = true;
          }
        }
      }
      return groupDescriptionMatch;
    });
    return filteredData;
  }
}

这两个函数都在过滤同一个对象,但是不同的键(类型和函数组)。函数组值使用正则表达式修改,因为下拉值包括索引号和逻辑中未使用的破折号。例子:

1 - myFunctionGroup --regex-->myFunctionGroup

这不是在 type 键中完成的。如何结合这两个功能?

标签: javascripttypescript

解决方案


所以我认为您正在努力解决的是关注点分离,而不是可重用性/抽象。我不得不稍微改写一些东西,这样它对我来说是可读的,事实证明你所做的大部分工作都可以用语言结构代替,所以你只剩下业务逻辑了。

一旦只剩下业务逻辑,很容易看出它非常简单,不需要重构。

const filterByOperationType = () => {
  if (!filterConditions[0].selected.length) {
    return [];
  }

  return operations.filter(({ operationDetails }) => {
    return filterConditions.some(fc =>
      fc.name === "Type" && fc.selected[0].text === operationDetails,
    );
  });
};

/** Filter the operations by function group when dropdown is used */
const filterByFunctionGroup = () => {
  if (!filterConditions[0].selected.length) {
    return [];
  }

  return operations.filter(({ functionDetails }) => {
    return filterConditions.some(fc =>
      fc.name === "Function group"
      && intoLetterOnlyWords(fc.selected[0].text) === functionDetails,
    );
  });
};

// Do some weird stuff to some letters
const intoLetterOnlyWords = (text) => text.match(/[a-zA-Z]+/g).join(" ");

如果您想更进一步,请关闭每个过滤器功能的关注点。


const createFilterBy = (nameToMatch: string, formatSelectedText = (t: string) => t) => () => {
  if (!filterConditions[0].selected.length) {
    return [];
  }

  return operations.filter(({ functionDetails }) => {
    return filterConditions.some(fc =>
      fc.name === nameToMatch
      && formatSelectedText(fc.selected[0].text) === functionDetails,
    );
  });
};

// Do some weird stuff to some letters
const intoLetterOnlyWords = (text: string) => text.match(/[a-zA-Z]+/g).join(" ");

const filterByFunctionGroup = createFilterBy("Function group", intoLetterOnlyWords);
const filterByOperationType = createFilterBy("Type");

推荐阅读