你可以做一个遗留的代码库,对提高质量有最大的影响?

当你在一个传统的代码库中工作时,将会对时间产生最大的影响,从而提高代码库的质量?

  • 删除未使用的代码
  • 删除重复的代码
  • 添加unit testing,以提高覆盖率低的testing覆盖率
  • 跨文件创build一致的格式
  • 更新第三方软件
  • 减less静态分析工具产生的警告(ieFindbugs)

代码库由许多开发人员在不同的专业知识水平下编写而成,其中很多领域都没有经过testing,有些则无法testing,所以没有花费大量时间编写testing。

  • 阅读Michael Feather的书“使用遗留代码有效地工作”

这是一本很好的书。

如果你不喜欢这个答案,那么我可以给出的最好的build议是:

  • 首先,停止制作新的遗留代码[1]

[1]:传统代码=没有unit testing的代码,因此是未知的

在没有自动化testing套件的情况下改变遗留代码是危险和不负责任的。 没有良好的unit testing覆盖率,你不可能知道这些变化会有什么影响。 Feathers推荐了一种“束缚”方法,在这种方法中,您需要隔离需要更改的代码区域,编写一些基本testing来validation基本假设,通过unit testing进行小的更改,然后从中解决问题。

注意:我不是说你需要停止一切,花几个星期为所有事情写testing。 恰恰相反,只是testing你需要testing和从那里工作的领域。

Jimmy Bogard和Ray Houston做了一个非常类似于这个主题的有趣的屏幕投射: http : //www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/06/pablotv-eliminating-static-dependencies-screencast。 ASPX

我使用约50名程序员编写和修改的传统1M LOC应用程序。

* Remove unused code 

几乎没用…只是忽略它而已。 你不会得到一个很大的投资回报(ROI)。

 * Remove duplicated code 

其实,当我修理东西的时候,我总是search重复的东西。 如果我发现了一些我把一个通用函数或注释所有代码的重复(有时候,放置一个通用函数的努力是不值得的)。 主要的想法是,我讨厌不止一次地做同样的动作。 另一个原因是因为总是有人(可能是我)忘记检查其他事件…

 * Add unit tests to improve test coverage where coverage is low 

自动化的unit testing是非常棒的…但是如果你有一个很大的积压,任务本身很难提升,除非你有稳定性问题。 和你正在工作的部分一起去吧,希望在几年之内你能有适当的覆盖面。

 * Create consistent formatting across files 

IMO在格式上的差异是遗产的一部分。 它给你一个关于谁写代码的提示。 这可以给你一些关于如何在代码的部分行为的线索。 做重新格式化的工作,并不好玩,它不会给你的客户带来任何价值。

 * Update 3rd party software 

只有在新的操作系统不支持新function或新版本的情况下才能执行此操作。

 * Reduce warnings generated by static analysis tools 

这是值得的。 有时候警告可以隐藏一个潜在的错误。

添加unit testing以提高testing覆盖率。 具有良好的testing覆盖率将允许您重构和改进function,而不用担心。

在CPPUnit的作者的着作中有一本关于遗产代码有效工作的书 。

对遗留代码添加testing比从头创buildtesting更具挑战性。 我从书中拿掉的最有用的概念是羽毛定义的“接缝”的概念

“在这个地方你可以改变你的程序中的行为而不用在那里编辑。

有时候,它的价值在于重构创build接缝,这将使未来的testing变得更容易(或者首先可能)。 谷歌testing博客在这个主题上有几个有趣的post,主要围绕着dependency injection的过程。

我想说的是“删除重复的代码”意味着你必须提取代码并将其抽象出来,以便在多个地方使用它 – 理论上,这样可以使错误更容易修复,因为只需修复一段代码,而不是许多代码片段,以修复它的一个错误。

我可以把这个问题联系起来,因为我现在在我的膝盖上有一个“那些”旧的代码库。 它不是真正的遗产,但它肯定没有遵循这些年的趋势。

我会告诉你,当他们每天都在烦我的时候,我会尽力解决这个问题:

  • logginginput和输出variables
  • 重构variables名称,使它们实际上意味着其他一些匈牙利语符号前缀,后跟三个字母的缩写,并带有一些不太明确的含义。 CammelCase是要走的路。
  • 我很害怕改变任何代码,因为它会影响到使用这个软件的数百个客户,而且有人会注意到甚至是最不明显的副作用。 任何可重复的回归testing将是一个祝福,因为现在是零。

剩下的就是花生。 这是遗留代码库的主要问题,他们真的耗尽了大量的时间。

我想说这很大程度上取决于你想用遗产代码做什么…

如果它将无限期地保持在维护模式,并且工作正常,什么都不做是最好的select。 “如果没有损坏,不要修理。”

如果工作不正常,删除未使用的代码并重构重复的代码将使debugging更容易。 但是,我只会对错误的代码进行这些更改。

如果你计划在2.0版本上添加unit testing并清理你将要提交的代码

良好的文档。 作为必须维护和扩展遗留代码的人员,这是头号问题。 如果不是彻底危险的改变你不明白的代码是很困难的。 即使你有足够的幸运可以交出文档化的代码,你对文档是否正确有把握? 它涵盖了原作者的所有隐含知识吗? 它说到所有的“技巧”和边缘情况?

良好的文档可以让原作者以外的人理解,修复和扩展糟糕的代码。 我会采取黑客攻击,但有充分的文件logging代码,我可以了解一周中的任何一天完美但不可思议的代码。

我对遗留代码所做的最重要的事情就是构build一个真正的API。 这是一个20世纪70年代风格的COBOL API,我已经构build了一个.NET对象模型,所有不安全的代码都在同一个地方,API的本地数据types和.NET数据types之间的所有转换都在一个地方,主要方法返回并接受数据集,等等。

这是非常困难的,而且我还知道它还有一些缺陷。 这也不是非常有效,所有的编组都在继续。 但另一方面,我可以构build一个DataGridView,将数据往返于一个15年前的应用程序,该应用程序在大约半小时内将其数据保存在Btrieve(!)中,并且工作正常。 当客户来到我的项目,我的估计是在几天,几个星期,而不是几个月和几年。

和Josh Segall所说的一样,我会说出来的。 我曾经在几个非常大的遗留系统上工作,而我发现最大的问题是跟踪我已经了解的特定代码段。 一旦我开始放置笔记,包括“待办事项”笔记,我就不再重新计算出我已经想清楚的内容。 然后我可以专注于这些代码段如何stream动和交互。

我想说的是,大部分情况下, 如果没有损坏,请不要修复。 如果它被破坏,那么继续修复和改善破坏的代码部分及其周围的代码。 您可以使用该错误或严重缺失function的痛苦来certificate改善该部分的努力和成本。

我不会推荐任何批量改写,重构,重新格式化,或者不进行实际业务或最终用户需求的unit testing。

如果你确实有机会解决某些问题,那么做对(第一次做对的机会可能已经过去了,但是既然你正在接触这个部分,不妨做正确的时间),这包括所有的你提到的物品。

所以总的来说,你不应该做任何事情。 你们应该尽一切办法,但是要以小部分和机会主义的方式来做。

在晚会之后,但以下可能值得做的地方经常使用或引用一个函数/方法:

  • 在遗留代码中,局部variables通常往往被错误地命名(通常是因为当一个方法被修改时它们的范围扩大了,而没有被更新来反映这个)。 重命名这些符合他们的实际目的可以帮助澄清遗留代码。
  • 即使只是稍微不同的布置方法也可以创造奇迹 – 例如,把一个if所有子句放在一行上。
  • 那里可能有陈旧/混乱的代码评论。 如果不需要的话,将它们移除,如果您绝对必须修改它们。 (当然,我不是主张删除有用的评论,只是那些有碍的评论。)

这些可能没有你想要的巨大的标题影响,但是它们的风险很低,特别是如果代码不能被unit testing的话。

Interesting Posts