【问题标题】:Is code duplication a sufficient reason to extract a method...?代码重复是提取方法的充分理由吗...?
【发布时间】:2010-11-17 21:45:04
【问题描述】:

...什么时候提取的方法会受到低内聚的影响(没有形成一个好的抽象并且名字很差)?

例如,你会给下面的方法起什么名字?

private void foobar() {
    Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID();
    socketAction.registerSession();
    socketAction._sess.runApplication();
}

这是我的另一个问题的可能重复:To DRY or not to DRY? On avoiding code duplication and retaining cohesion - 或者我从更有经验的程序员那里得到一些建议的绝望方式(希望你原谅我)。请检查上面的链接 - 它包含我在这里展示的示例所基于的代码。

【问题讨论】:

  • 复制在哪里?我在您的示例中看不到它;而且我不确定重命名方法与方法提取的相关性如何?当然,当您将代码提取到新方法中时,您必须为其命名 - 但您的问题不是更多关于重复的充分理由吗?

标签: design-patterns language-agnostic architecture


【解决方案1】:

我构建code clone detectors。我经常看到多组代码 A B C P Q 被发现为克隆,其中 A B C 在概念上是连贯的,而 P Q 在概念上是连贯的,但 ABC 和 PQ 是不相关的。克隆检测器(或未受过代码阅读的人)将看到与克隆相同的序列。是的,您可以尝试从 A B C P Q 中创建一个糟糕的抽象 FOOBAR,但从有原则的读者的角度来看,您最好将 A B C inyo 抽象为一个抽象,然后考虑如何处理 P Q 克隆。

我不知道这是否适用于你的情况,因为你所有的调用都是 socketactions(A B C?)而且我不熟悉你的界面。

【讨论】:

    【解决方案2】:

    如果重复是“坏的”,那么是的,我会考虑提取它,但您总是希望在这与其他问题之间取得平衡。

    另外,根据Extract Method Refactoring (C#),提取方法有4个原因,重复是其中之一。

    其他(如链接文章所述)是:

    • 通过强调离散的、可重复使用的方法来鼓励最佳编码实践。
    • 鼓励通过良好的组织进行自我记录的代码。使用描述性名称时,高级方法更像是一系列 cmets。
    • 鼓励创建更细粒度的方法以简化覆盖。

    【讨论】:

    • 可以在here 找到带有重复代码的完整代码示例,但我想您已经看过它,因为您也回答了其他问题。我在某处读过它,不记得现在在哪里(我会尝试找到参考)只有在名称揭示其意图时提取方法才有意义,这样您就不必检查实施以查看发生了什么。因此我的问题是——你会为了减少重复而牺牲可读性吗?
    • 我认为一个人可能不应该只是在看到重复时自动提取方法 - 有时最好重组整个事情直到提取似乎是最自然的事情 - 如果你知道我我想说。
    【解决方案3】:

    看了你的“To DRY...”问题后,我认为应该提取这个函数——重复的味道足以证明它的合理性。

    尝试从您在该问题中显示的内部类推断 SocketAction 类的用途,似乎 StartSession 是该函数的合理名称。

    【讨论】:

      【解决方案4】:

      这是关键,如果您必须更改其中一个副本(以修复错误或添加功能),您是否还必须更改其他副本?如果答案是“是”,则将它们组合成一个函数。

      我也注意到,你的函数的所有三行都处理了一个 socketAction,而 this/self 根本没有被引用。这表明该方法应该是 socketAction 类的一部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-21
        • 1970-01-01
        • 1970-01-01
        • 2011-06-08
        • 1970-01-01
        相关资源
        最近更新 更多