我看过几次推荐使用《传统代码有效工作》的书。本书的重点是什么?

除了添加单元/集成测试然后进行重构之外,处理遗留代码还有很多吗?

评论

Diomidis Spinellis的简短评论

当然,重点是添加测试,然后进行重构。这本书主要是关于如何设法测试令人费解的代码,在这一点上有很多令人大开眼界的事情。可以说羽毛根本没有俘虏任何人!

也许您应该只看这本书

不错的评论在这里:andreaangella.com/2014/03/…

@yannis简短审阅链接已经消失,没有重定向。这是同一个人Andrea Angella进行评论的新链接。

#1 楼

遗留代码的关键问题是它没有测试。因此,您需要添加一些(然后添加更多...)。

正如@mattnz指出的那样,这本身将需要很多工作。但是,遗留代码的特殊问题在于它从未设计为可测试的。因此,通常情况下,这是一团乱七八糟的意大利面条代码,很难或根本不可能隔离要进行单元测试的小零件。因此,在进行单元测试之前,您需要重构代码以使其更具可测试性。

但是,为了安全地进行重构,您必须进行单元测试,以确保您所做的更改没有破坏任何东西。这是遗留代码的陷阱22。

这本书教您如何通过对代码进行绝对最小,最安全的更改来实现这一目标,以启用第一个单元测试。这些并不是为了使设计更好,而只是为了进行单元测试。实际上,有时它们确实会使设计更难看或更复杂。但是,它们允许您编写测试-一旦有了单元测试,就可以自由地改进设计。

有很多技巧可以使代码可测试-有些可以很明显,有些根本没有。如果不阅读本书,有一些我从未想过的方法。但是更重要的是,Feathers解释了使代码单元可测试的确切原因。您需要减少依赖性并在代码中引入障碍,但是出于两个明显的原因:



传感-为了检查和验证执行一段代码的效果和

分离-首先将特定的代码片段放入测试工具。

安全地削减依赖关系可能很棘手。引入接口,模拟和依赖注入是很干净,很不错的目标,但此时不一定要安全。因此有时我们不得不求助于被测类的子类,以覆盖通常会例如向数据库发出直接请求。在其他时候,我们甚至可能需要在测试环境中用伪造的依赖类/ jar替换依赖类/ jar。接缝是代码中可以更改程序行为而不修改代码本身的地方。在代码中建立接缝可以分离被测代码段,但是即使您很难或不可能直接进行操作(例如,由于调用在另一个对象或子系统中进行更改),也可以使您感知被测代码的行为,其状态无法直接从测试方法中查询)。

此知识使您可以注意到最讨厌的代码堆中的可测试性种子,并找到最少,破坏最少,最安全的代码到达那里的变化。换句话说,为避免进行“显而易见的”重构,而重构有可能在不引起您注意的情况下破坏代码-因为您还没有单元测试来检测到这一点。

评论


请注意,当以上答案说“单元测试”时,实际上是指“自动测试”。对于旧版应用程序,实际上,最初有用的自动化测试中有很大一部分实际上是集成测试(测试逻辑执行较大部分的整体代码,并且可能由于许多不同位置的缺陷而导致失败),而不是真正的单元测试(旨在仅分析一个模块并分别执行更小的代码部分)。

– Lutz Prechelt
19年1月18日在8:40

#2 楼

快速获得有效使用遗留代码工作的关键点的方法


阅读本书前两年写的Michael Feathers的12页PDF。
看迈克尔·费瑟斯的演讲:68张幻灯片

听迈克尔·费瑟斯的播客访谈。例如。这30分钟的Hanselminutes情节。


评论


该Hanselminutes页面上的MP3链接已断开,但hanselminutes.com/165/…上的那个链接不是-s3.amazonaws.com/hanselminutes/hanselminutes_0165.mp3。

– Peter Mortensen
2014-2-22在8:09

感谢rosston修复了PDF链接。看起来objectmentor.com已经消失了-也许“鲍勃叔叔”倒闭了吗?

– MarkJ
16-2-18在14:07

我不确定对象导师怎么了,但是这些天鲍勃叔叔为第七光工作。

–法律
16年2月18日在22:03

#3 楼

我在数百万行代码的代码库中工作,其中一些代码可以追溯到1980年代。它只是软件,因此只需编写一些单元测试即可,因此您可以对其进行重构,并使其变得更好。

这里的关键词只是-它是一个四个字母的词,不属于任何程序员的词汇表,更不用说在传统系统上工作的人了。

您认为编写单元测试和测试一小时的开发工作需要花费多长时间?为了讨论起见,让我们再说一个小时。

那个拥有200多年历史的百万生产线的旧系统投入了多少时间?假设有20位开发人员,他们使用20年乘以2000小时/年(他们非常努力)。现在让我们选择一个数字-您拥有新的计算机和新的工具,而且比起初写这篇$%^^的家伙要聪明得多-假设您有十本。你有40个人年,好吗...?

因此,您的问题的答案还有很多。例如,该例行程序有1000行(我有几行超过5000行),它过于复杂,而且是意大利面条。只需几天(再加上四个字母的单词)就可以将其重构为几百行例程和几行二十行助手,对吗?错误。在这1000行中隐藏了100个错误修复程序,每个错误修复程序都是未记录的用户需求或不明显的情况。这是1000行,因为原始的100行例程无法完成工作。

您需要以“如果没有破裂,请不要修复”的思维定势进行工作。当它损坏时,在修复它时需要非常小心-随着它变得更好,不要意外更改其他内容。请注意,“中断”可能包含无法维护但可以正常运行的代码,这取决于系统及其用途。问“如果我搞砸了,使情况变得更糟,会发生什么”,因为有一天,你将不得不告诉老板的老板为什么选择这么做。变得更好。您将有预算可用于工作,时间轴等。如果您不这样做,那就去做一个。当金钱/时间用完时,不要再做得更好了。添加功能,给自己一点时间使其变得更好。修复错误-再次花一些额外的时间,使其变得更好。永远不要交付比开始时更糟糕的东西。

评论


感谢您的提示!这些是您的还是书中的?

–武器
2011年11月28日在8:50

可能两者兼而有之-在完成这项工作几年后,我读了这本书,应该读得有点古怪。像任何一本好书一样,它会使您挑战当前正在做的事情,加强您所做的大部分工作,但没有针对您所遇到的特定问题的所有答案。

–mattnz
11年11月28日在19:14

“这是1000线,因为原始的100线例行程序无法完成任务。”因此,实际情况很少如此。通常是1,000行,这仅仅是因为原始开发人员卷起了袖子开始编码,而后才花了一点时间进行规划或设计。

–斯蒂芬·托瑟(Stephen Touset)
2012年8月22日15:16



不。我是说,在大多数情况下(我个人遇到过),有1000条行例程明确表明人们在考虑如何编写适当的抽象之前就开始编写代码。千行例程实际上从定义上讲太复杂了–您是在说一千行例程具有数百个隐藏的,未注释的错误修复程序,这是负责任的开发人员的标志?

–斯蒂芬·托瑟(Stephen Touset)
2012年8月23日在4:53



如果您相信此站点上的每条帖子,那么每个人都必须处理1000行意大利面条代码,但没人写过。根据我的经验,开发人员的特点是1000(和10000)行例程,他们会竭尽所能,以支付付工资的老板所要求的。我觉得这很侮辱和自大,以至于许多开发人员在不了解情况的情况下随意在旁观地发表评论,而不必向社区公开自己的作品进行批评。

–mattnz
2012年8月24日在1:41

#4 楼

本书有两个要点。


遗留代码是任何没有测试覆盖的代码。
每当需要更改遗留代码时,都应该请确保它具有覆盖范围。相反,每当您必须更改旧版代码(用于新功能或错误修复)时,请花点时间删除其旧版状态。

评论


+1优点:“每当需要更改旧代码时,请花点时间删除其旧状态。”

–约翰
2011-12-14 15:03

删除旧版状态,请投票:)

–雷切尔
2012年3月30日16:54

#5 楼

一言以蔽之,这是真的-添加测试和重构的全部内容。 />