如何重构一个复杂的JavaScript函数?

时间:2017-05-26 13:08:30

标签: javascript object refactoring prototype

我试图重构一系列将初始序列解卷积为最终序列的方法。我可以看到三种可能的解决方案,但我真的不明白我应该用什么标准来选择它们。

为了使示例更容易理解,我已经简化了步骤和操作的次数。

选项1 - 构造函数,设置原型中的方法

function Deconvoluter(initialValue) {
  this.initialValue = initialValue
  this.finalValue = null
}

Deconvoluter.prototype = {
  deconvolute() {
    this.firstStep()
    this.secondStep()
    return this.finalValue
  },

  firstStep() {
    this.finalValue = this.initialValue + 1
  },

  secondStep() {
    this.finalValue = this.finalValue + 10
  }
}

d = new Deconvoluter(0)
d.deconvolute() // 11

选项2 - 使用私有方法的常规函数​​

function deconvolute2(initialValue) {
  this.initialValue = initialValue
  this.finalValue = null
  function firstStep() {
    this.finalValue = this.initialValue + 1
  }

  function secondStep() {
    this.finalValue = this.finalValue + 10
  }

  firstStep()
  secondStep()
  return this.finalValue
}

deconvolute2(0) // 11

选项3 - 具有方法属性的常规函数​​

function deconvolute3(initialValue) {
  this.initialValue = initialValue
  this.finalValue = null
  this.firstStep = function() {
    this.finalValue = this.initialValue + 1
  }

  this.secondStep = function() {
    this.finalValue = this.finalValue + 10
  }

  this.firstStep()
  this.secondStep()
  return this.finalValue
}

deconvolute3(0) // 11

选择这些选项是个人偏好还是比其他选择更好?如果是这样,是否有其他两种情况会更好的情况?

更新

我已经意识到我被吸引到第三个选项的原因是因为我希望能够访问中间步骤。这会是一个更好的实施吗?

选项4 - 装饰器模式

function ComplexCalculation(initialValue) {
  this.initialValue = initialValue

  setFirstStepCalculation(this)
  setSecondStepCalculation(this)
  setFinalValue(this)
}

function setFirstStepCalculation(calculation) {
  // much longer calculation goes here
  calculation.firstStepCalculation = calculation.initialValue + 1
}

function setSecondStepCalculation(calculation) {
  // much longer calculation goes here
  calculation.secondStepCalculation = calculation.firstStepCalculation + 10
}

function setFinalValue(calculation) {
  // much longer calculation goes here
  calculation.finalValue = calculation.secondStepCalculation + 100
}

cc = new ComplexCalculation(0)
cc.secondStepCalculation // 11
cc.finalValue // 111

1 个答案:

答案 0 :(得分:3)

在选项2和3中使用this毫无价值,使用finalValue初始化null是多余的。我推荐选项2的这个变种:

function deconvolute2(initialValue) {
    let finalValue;

    function firstStep() {
        finalValue = initialValue + 1
    }

    function secondStep() {
        finalValue = finalValue + 10
    }

    firstStep()
    secondStep()
    return finalValue
}

deconvolute2(0) // 11

如果你想拥有一个持有状态的对象(可以通过this访问)并使用各种方法来改变这种状态,那么使用选项1的模式是有意义的。

因此,例如,如果您不仅使用deconvolute方法而且还使用convolute方法,那么选项1将更为可取。

firstStepsecondStep函数的大小和复杂性并不重要。