首页 > 解决方案 > 重构多种方法使用的相似代码

问题描述

我有这样的情况:有两种方法(我无法更改,因为它们来自抽象类)from()to()必须执行相同的代码,只有很小的区别。我创建了第三种方法,并使用了一个布尔变量来知道这两种方法中的哪一种称为第三种方法。现在,有没有办法以更干净的方式写这个?

protected from(x: any): any[] {
  return this.convertArray(true, x);
}

protected to(y: any): any[] {
  return this.convertArray(false, y);
}

private convertArray(isFrom: boolean, inArray: any[]): any[] {
  const array = [];
  if (this.types.length === 1) {
      // ... some code here ...
      array.push(isFrom ? adapter.from(value) : adapter.to(value));
  } else {
      // ... some code here ...
      array.push(isFrom ? adapter.from(inArray[i]) : adapter.to(inArray[i]));
  }
  return array;
}

标签: javascripttypescriptrefactoring

解决方案


您还有其他一些选择:

  1. 您可以使用字符串作为方法名称和括号表示法从以下位置获取方法adapter

    private convertArray(isFrom: boolean, inArray: any[]): any[] {
      const array = [];
      const method = isFrom ? "from" : "to";          // ***
      if (this.types.length === 1) {
          // ... some code here ...
          array.push(adapter[method](value));         // ***
      } else {
          // ... some code here ...
          array.push(adapter[method](inArray[i]));    // ***
      }
      return array;
    }
    
  2. 您可以使用通过创建的包装函数bind(因此this在调用中是adapter):

    private convertArray(isFrom: boolean, inArray: any[]): any[] {
      const array = [];
      const method = (isFrom ? adapter.from : adapter.to).bind(adapter); // ***
      if (this.types.length === 1) {
          // ... some code here ...
          array.push(method(value));         // ***
      } else {
          // ... some code here ...
          array.push(method(inArray[i]));    // ***
      }
      return array;
    }
    

    或(称其为“2(b)”)通过箭头函数:

    private convertArray(isFrom: boolean, inArray: any[]): any[] {
      const array = [];
      const op = isFrom ? value => adapter.from(value) // ***
                        : value => adapter.to(value);  // ***
      if (this.types.length === 1) {
          // ... some code here ...
          array.push(op(value));                       // ***
      } else {
          // ... some code here ...
          array.push(op(inArray[i]));                  // ***
      }
      return array;
    }
    
  3. 或者直接通过以下方式使用该方法.call

    private convertArray(isFrom: boolean, inArray: any[]): any[] {
      const array = [];
      const method = isFrom ? adapter.from : adapter.to; // ***
      if (this.types.length === 1) {
          // ... some code here ...
          array.push(method.call(adapter, value));       // ***
      } else {
          // ... some code here ...
          array.push(method.call(adapter, inArray[i]));  // ***
      }
      return array;
    }
    

推荐阅读