我看过推荐过几次《有效使用旧版代码》的书。本书的重点是什么?
除了添加单元/集成测试然后进行重构之外,处理遗留代码还有更多的事情吗?
我看过推荐过几次《有效使用旧版代码》的书。本书的重点是什么?
除了添加单元/集成测试然后进行重构之外,处理遗留代码还有更多的事情吗?
Answers:
遗留代码的关键问题是它没有测试。因此,您需要添加一些(然后添加更多...)。
正如@mattnz指出的那样,这本身将需要大量工作。但是,遗留代码的特殊问题是它从未设计为可测试的。因此,通常情况下,这是一团乱七八糟的意大利面条代码,很难或根本不可能隔离要进行单元测试的小零件。因此,在进行单元测试之前,您需要重构代码以使其更具可测试性。
但是,为了安全地进行重构,您必须进行单元测试,以确保所做的更改没有破坏任何东西。这是遗留代码的第22条。
这本书教您如何通过对代码进行绝对最小,最安全的更改来实现这一目标,以启用第一个单元测试。这些并不是为了使设计更好,而只是为了进行单元测试。实际上,有时它们确实会使设计更难看或更复杂。但是,它们允许您编写测试-一旦有了单元测试,就可以自由地改进设计。
有很多技巧可以使代码可测试-有些很明显,有些根本没有。如果不阅读本书,有一些我从未想过的方法。但是更重要的是,Feathers解释了使代码单元可测试的确切原因。您需要削减依赖性并在代码中引入障碍,但这有两个明显的原因:
安全地削减依赖关系可能很棘手。引入接口,模拟和依赖注入是很干净,很不错的目标,但此时不一定要安全。因此,有时我们不得不求助于被测类的子类,以覆盖某些方法,该方法通常会例如启动向数据库的直接请求。其他时候,我们甚至可能需要在测试环境中用伪造的依赖类/ jar替换依赖类/ jar。
对我来说,羽毛带来的最重要的概念是接缝。接缝是代码中可以更改程序行为而无需修改代码本身的地方。在代码中建立接缝可以分离被测代码段,但是即使在很难或不可能直接执行时(例如,由于调用在另一个对象或子系统中进行更改),也可以使您感知被测代码的行为。 ,其状态无法直接从测试方法中查询)。
这些知识使您可以注意到最讨厌的代码堆中的可测试性种子,并找到到达那里的最小,破坏性最小,最安全的更改。换句话说,为了避免“明显”的重构具有破译密码没有你注意到的风险-因为你不还具备单元测试来检测。
获得有效使用旧版代码的关键点的快速方法
我在数百万行代码的代码库中工作,其中一些代码可以追溯到1980年代。它只是软件,因此只需编写一些单元测试即可,因此您可以进行重构,使其变得更好。
这里的关键词只是-它是一个四个字母的单词,不属于任何程序员的词汇表,更不用说在遗留系统上工作的人了。
您认为编写单元测试和测试一小时的开发工作需要花费多长时间?为了讨论起见,让我们再说一个小时。
该百万线,拥有20年历史的旧系统投入了多少时间?假设,有20位开发人员使用了20年时间乘以2000小时/年(他们非常努力)。现在,让我们选择一个数字-您拥有新的计算机和新的工具,并且比起最初写这篇$%^^的家伙要聪明得多-假设您值得其中10个人。你有40个人年,好吗...?
因此,您的问题的答案还有很多。例如,该例行程序有1000行(我有几行超过5000行),它过于复杂,而且是意大利面条。只需几天(再加上四个字母的单词)就可以将其重构为几百行例程和更多的二十行助手,对吗?错误。在这1000行中隐藏了100个错误修复程序,每个错误修复程序都是未记录的用户要求或不明显的情况。这是1000行,因为原始的100行例程无法完成工作。
您需要以“ 如果没有破裂,请不要修复 ” 的思维方式进行工作。当它损坏时,在修复它时需要非常小心-随着它变得更好,不要意外更改其他内容。请注意,“中断”可能包含无法维护但可以正常运行的代码,这取决于系统及其用途。问“如果我搞砸了,使情况变得更糟,会发生什么”,因为有一天,你将不得不告诉老板的老板为什么选择这么做。
这些系统总是可以做得更好。您将有预算可用于工作,时间轴等。如果您不这样做,那就去做一个。当金钱/时间用完时,不要再做得更好了。添加功能,给自己一点时间使其变得更好。修复错误-再次花费一些额外的时间并使它变得更好。永远不要交付比开始时更糟糕的东西。