代码维护:在扩展新代码时是否保持一致的错误模式?


45

我必须扩展项目的现有模块。我不喜欢它的完成方式(涉及很多反模式,例如复制/粘贴的代码)。由于多种原因,我不想执行完整的重构。

我是不是该:

  • 使用现有约定创建新方法,即使我觉得错了,也可以避免对下一个维护者造成混淆并与代码库保持一致?

要么

  • 尝试使用我感觉更好的方法,即使它在代码中引入了另一种模式?

精确度在第一个答案后进行了编辑:

现有的代码不是一团糟。很容易理解和理解。但是,它引入了许多可以通过良好设计避免的样板代码(结果代码可能会变得更难遵循)。在我当前的情况下,这是一个很好的旧JDBC(内置弹簧模板)DAO模块,但是我已经遇到了这个难题,我正在寻求其他开发人员的反馈。

我不想重构,因为我没有时间。而且即使有时间,也很难证明一个完整的正常工作的模块需要重构。重构成本将超过其收益。请记住:代码并不凌乱或过于复杂。我不能在那里提取一些方法并在这里介绍一个抽象类。这在设计中更是一个缺陷(我认为极端“保持愚蠢简单”的结果)

因此,也可以这样问这个问题:
作为开发人员,您是喜欢维护简单的愚蠢无聊的代码,还是希望有一些帮助程序来代替您的愚蠢无聊的代码?

最后一种可能性的缺点是,您必须学习一些知识,也许您还必须维护简单的愚蠢无聊代码,直到完成完整的重构为止)


非常有趣的问题!
菲利普

1
维护简单而乏味的愚蠢代码-从定义上来说很容易。我宁愿过着轻松的生活,每天早点离开。
quick_now 2011年

是的,但是我懒得做无聊的愚蠢代码:)我宁愿努力工作2到3天来构建可以为我做这部分工作的东西!
纪尧姆

1
愚蠢或无聊的人何时容易感到困惑?
埃里克·雷彭

嗨,Erik,有时候本可以分解的代码更易于阅读:同一件事要花很多时间,而且代码也很简单。您可以连续阅读它而无需考虑它,并且可以以线性方式进行调试。没有隐藏的复杂性。
纪尧姆

Answers:


42

重构最好以小步骤完成,并且最好仅在有单元测试覆盖代码的情况下进行。(因此,如果您还没有测试,请尝试先编写它们,然后在此之前,坚持最简单,最简单的方法,最好是自动重构。这方面的巨大帮助是Michael Feathers的Legacy Code有效地工作。)

通常,只要您触摸一下代码,就可以稍微改善一下代码。遵循“ 童子军规则”由Robert C. Martin创造),将代码清理干净,而不是找到它。添加新代码时,请尝试使其与现有错误代码分开。例如,不要将其埋在长方法的中间,而应添加对单独方法的调用,然后将新代码放入其中。这样,您可以在现有代码库中逐渐增加更大的干净代码孤岛。

更新资料

重构成本将超过其收益。[...]作为开发人员,您是喜欢维护简单的愚蠢无聊代码还是希望有一些助手在您的位置进行愚蠢无聊的代码?

我强调了我认为这是关键。我们进行重构之前,总是值得评估重构的成本和收益。与您的情况一样,我们大多数人的重构资源都有限,因此我们必须明智地使用它们。花很少的时间在重构上,以最少的努力带来最大的收益。

作为一个有创造力的人,我当然更喜欢生成完美,优美而优雅的代码,并重写所有与我的理想不符的东西:-)尽管实际上,我有报酬来生产能够为其用户解决实际问题的软件,所以我应该考虑在长期内为他们的钱创造最大的价值。

重构的好处只有在节省大量时间和精力来长期理解,维护,修复和扩展代码时才会显现。因此,如果很少或从未触及过一段代码(无论多么难看),则其中没有已知的错误,而且在可预见的将来,我也不知道任何即将出现的功能需要我去触摸它,所以我宁愿离开它和平。


7
容易陷入“代码已经很烂,也可能会继续下去……”的陷阱。好的程序员不会。好答案。
sevenseacat 2011年

尽管这很可能是最安全的方法(由于测试,代码可以保证正常工作),但仍然会导致问题中提到的问题。代码中引入了不同的模式。通常,我相信您应该花一些时间立即重构所有内容(执行TDD时,最好使用中间步骤),这样就不会出现中间不一致的状态。完成后,将代码提交到源代码管理。
史蒂芬·杰里斯

2
@Steven,如果可以承受的话,可以立即重构所有内容。但是,在大多数现实生活项目中,您不能只是停止一切并连续花费几天或几周来进行重构。即使您很幸运有一位支持它的经理,该项目仍需要继续进行。
彼得Török

1
@Steven,这取决于-请参阅上面的更新。
彼得Török

1
@PéterTörök:很好的更新!考虑到现实因素的完美描述。
史蒂文·杰里斯

4

由于您没有时间重构并且代码是可维护的,因此请保持一致。下次一定要在估计中包括重构。


3

当周围的代码状态良好时,保持一致只会帮助下一个开发人员。想一想您花了多长时间才能理解手头的代码并找到正确的“扩展点”来添加您的更改。如果您遵循当前趋势,那么下一个家伙在必须进行更改时必须理解现有代码以及您的新代码。

如果您将代码重构为有意义的功能,那么下一个人将更容易理解所发生的事情,并且将花费更少的精力来添加其更改。这样想吧。假设下一个家伙是你。当您重新访问该代码块,现在正在看到的混乱或更逻辑化的结构时,您希望看到什么?


3

一致性具有很高的优先级。显然,每个人都在自己的头脑中更喜欢一个优雅的DRY解决方案,而不是每个地方都复制粘贴的样板,但是您真的希望在同一代码库中使用两种不同的方法而不是始终采用一种方法吗?如果有人发明了更智能的解决方案并且不一致地应用该怎么办?然后,您可以采用三种不同的方式来做同一件事。

我已经看到了很多混乱的代码,这些代码是由开发人员找到一种“更好的方式”来做某事的结果,而不是始终如一地将其应用于代码库。如果它是随着时间的推移逐步应用新模式的计划和协调战略的一部分,那么它可能会起作用,但是实施的每个模式都存在使整个系统变得更糟的风险。

也许您可以考虑以较小的步骤进行重构,以使每一步都可以一次应用于整个代码库。例如。在每次迭代中,将样板的一小部分提取为辅助函数。随着时间的流逝,您最终将获得所有帮助类的样板。由于它不是经过设计而是经过扩展,因此看起来可能很丑陋,但是由于您将所有代码都放在一个位置,因此现在可以修复此问题。


+1“然后,您可以采用三种不同的方式来做同一件事。” 我在从事的每个企业项目中都看到了这一点。我要说的是,甚至在您仔细检查代码以确保没有其他代码正在尝试处理您决定要重构的丑陋代码之前,不要尝试重构。有时,最好坚持遵循样板惯例,至少直到您对代码进行了完整的阅读为止。
TK-421

1

消除重复代码的任何重构都是很好的重构,除非临近最后期限,否则不应推迟。一次重构所花费的时间很容易由将来的实现所弥补的时间来弥补。由于重构,内部工作方式不再可见,因此它应该变得更易于理解,而不是很难理解。

在我看来,重构代码更难遵循,这是一个普遍的误解。通常,这只是那些只了解重构内容而不是重构结果的人的争论。对于新来者来说,重构的结果将更加清晰。

任何错误/功能都可以在以后的某个时间在中央位置修复/实现,并在您的应用程序中随处可见。这是一个巨大的收益,通常被低估了。通常,组件的整体重构不会花费那么长时间。(用天而不是数月),将其与由于错误而浪费的时间进行比较时,必须了解可能已经重构的代码,重构的成本将降至最低。

有关PéterTörök答复的最新信息:是不是因为“需要时间”而推迟重构,以后重构的时间却增加了吗?重构不应该花费很长时间,如果要做得更多。

如何向老板解释,您将花费几天的时间编写不会对产品造成任何影响的代码,这很困难,而且是一个完全不同的问题。:)


1
“如何向老板解释,您将花费几天的时间编写不会给产品增加任何东西的代码,这很困难,而且是一个完全不同的问题。” 不错的尝试;-)不幸的是,在现实生活中,我们也需要解决这个问题。这就是为什么逐步进行更实用。作为两个小时的任务的一部分,您可以完成半个小时的重构,而您的经理甚至不需要了解它。OTOH在重构中花了整整两天的时间很少被忽视。
彼得Török

@PéterTörök:我对帖子进行了一些更新。当然,您仍然会遇到现实情况,不允许您花时间进行重构。但我坚信,从理论上讲,这总是有时间的。(除非您知道您正在使用的代码将在不久的将来不再受支持)
Steven Jeuris,2011年

正如他们所说,在理论上,实践与理论之间没有太大区别。但是,在实践中... :-)在现实生活中,您可能不会总是收回在重构上花费的成本。我对此扩大了答案。
彼得Török

1
去除重复代码的重构并不总是很好;在当今的业务规则下,两种方法可能完全相同,但在明天的情况下可能完全相同。例如,一个AcmeLockerBank人可能有一个getRow(int itemIndex)返回的方法,index % 5而一个人AcmeButtonPanel可能有一个相同的方法,因为储物柜和按钮板的编号方式都相同。如果当今的储物柜中没有一个具有索引超过1000的项目,但是某些按钮面板却有索引,并且将来的储物柜对索引在1000-1999范围内的行使用不同的行距...
超级猫

1
...如果储物柜和纽扣库具有不同的getRow方法,则向储物柜中添加其他行为将很容易,但如果功能已合并为通用方法,则可能会更加困难。
2015年

0

在以您自己的样式(可以轻松扩展)引入新代码的同时,您是否不能创建一个可以用作旧代码的外观的新接口/类?



0

作为开发人员,您是喜欢维护简单的无聊代码,还是希望有一些助手来代替您的愚蠢代码?

我不明白修改后的问题。我认为大多数人,就像我自己,宁愿不维护“愚蠢无聊的代码”。对不起,我不知道您所说的帮手是什么意思。

张贴者通过不立即进行较大更改来回答自己的问题。好的选择。我对开发人员的傲慢有疑问,他们知道什么对业务最有利。狡猾的大重构...因为您比老板更了解?任何有能力的经理都可以权衡收益。

如果不能选择重构,那么问题将更多地是在讨论正确的时间,地点等。一致性非常重要。然而,寿命长的代码通常可以从“更新”中受益。其他人对此进行了讨论...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.