将 Temp 替换为查询

2022-09-03 17:10:17

现在,人们普遍推荐使用“用查询替换临时”重构方法,但似乎效率非常低,收益很小。

来自Martin Fowler网站的方法给出了以下示例:

将表达式提取到方法中。将 temp 的所有引用替换为表达式。然后,可以在其他方法中使用新方法。

    double basePrice = _quantity * _itemPrice;
    if (basePrice > 1000)
        return basePrice * 0.95;
    else
        return basePrice * 0.98;

成为

    if (basePrice() > 1000)
        return basePrice() * 0.95;
    else
        return basePrice() * 0.98;


double basePrice() {
    return _quantity * _itemPrice;
} 

为什么这是一个好主意?当然,这意味着计算是不必要的重复,并且您有调用函数的开销。我知道CPU周期很便宜,但像这样扔掉它们似乎很粗心?

我错过了什么吗?


答案 1

这是一个重构,很重要,因为它是对单一责任的重构,它是DRY失败的解决方案!

temps的主要问题(特别是在使用长方法的朴素代码中,数百行长!)是它们是可变的,本地状态。显而易见的风险(正如福勒所讨论的?)是,有人可能会在长期方法的中途做出改变,并在最后打破一些东西。(已看过此费用产生的)

没有测试,这种方法有无数的依赖关系 - 真是一团糟!:)

删除临时任务是关于重构到单一责任。

示例 - 今天我发现了一个错误,它与将错误的临时变量传递到服务中有关。如果我删除临时工(有几个,所有字符串),那么这个错误(疏忽)就不会发生。

我的方法持有临时变量的原因是它正在做它不应该的工作......这个逻辑被类似的类重复...一切都一致吗?不!

通过删除 temp,我还将代码重构为具有适当责任的类,可以通过一些简单的测试来覆盖 110%。

没有巨大的夹具来测试一些琐碎的东西

如果我调用一些昂贵的东西,我会将结果作为值对象/聚合返回。“临时代码”可能应该由聚合内部化。

因此,删除临时工会将您推入集中(单一)责任 - > SOLID!


答案 2

我现在正在重读重构,其中一个原因是第116页末尾的以下引用。Extract Method

背景:他描述,如果要提取的代码很难使用局部变量。Extract Method

临时变量通常非常丰富,以至于它们使提取变得非常尴尬。在这些情况下,我尝试通过使用将临时替换为查询(120)来降低温度。...

因此,一个重构可能依赖于首先执行另一个重构,这本身并不明显。另一个例子是在“替换”之前。Inline MethodMethod with Method Object


推荐