【问题标题】:How to refactor a complex JavaScript function?如何重构一个复杂的 JavaScript 函数?
【发布时间】:2017-05-26 13:08:30
【问题描述】:

我正在尝试重构一堆将初始序列反卷积为最终序列的方法。我可以看到三种可能的解决方案,但我真的不明白应该使用什么标准在它们之间进行选择。

为了使示例更易于理解,我简化了步骤数和操作。

选项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

【问题讨论】:

    标签: javascript object refactoring prototype


    【解决方案1】:

    在选项 2 和 3 中使用 this 确实没有任何价值,使用 null 初始化 finalValue 是多余的。我推荐选项 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 函数的大小和复杂性并不重要。

    【讨论】:

    • 谢谢!您认为使用this 的有效用例是什么?如果 firstStepsecondStep 有 20 行长,你的答案会改变吗?
    • 您对我更新的选项 4 有何看法。提供对中间值的访问是否是一个合理的选项?
    • 嗨@nachocab,IMO 如果你发布另一个问题而不是继续编辑这个问题并添加更多请求会更好?祝你好运!
    猜你喜欢
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多