我可以采取什么方法来降低在复杂的旧版应用程序中引入新错误的几率?


10

在我工作的地方,我经常不得不在旧系统(.NET 1)中开发(和修复错误)谁的代码是完整的意大利面条-对变量名,程序结构或注释不加考虑。

因此,我花了很长时间才了解需要更改哪些位,并且由于进行了修改,我经常“破坏”现有软件。我真的真的想花几个月的时间(与同事),通过它去重构,但现有的开发人员都看不到需要-也不觉得孤单时间讨论这个(系统是巨大的)。

我担心必须处理它的代码,因为花几天的时间来修复某些问题,才发现我已经破坏了其他内容。这显然使我看起来不称职-那么我该如何处理呢?


Answers:


16

开始为您正在研究的零件编写测试。您可以尝试如下工作流程:

  1. 为要更改的零件编写测试。这也将帮助您了解现有代码的行为。
    • 重构代码以支持测试(如果需要),但是如果时间短,则可能需要编写非单元测试。
  2. 运行测试以确保一切正常。
  3. 进行更改。如果需要,本着不断进行代码改进的精神进行重构,但是不要气carried。
  4. 重新运行测试以确保您保持相同的功能。

如果您不放弃测试,则随着时间的流逝,您将建立一个测试套件,该套件应涵盖应用程序的最重要(和/或易失)部分,并且进行更改将变得更加容易和安全。

您可能还会发现Michael Feathers的《有效处理旧版代码》很有帮助。


1
+1表示“ ...,但是如果时间短,您可能希望编写非单元测试。”!
Marcie

1
好答案。@ m.edmondson在重构时,您可能还会发现代码的某些部分是“巨大的”,因为到处都有重复项,并且在重构时,它变得越来越小,越来越简单。
Alb

6

我喜欢遵循鲍勃·马丁叔叔童子军规则

“当您遇到一堆乱七八糟的旧东西时,您所要做的就是……停止制造混乱并开始清理它们。

这并不意味着您要召集经理进入会议室,并告诉他们在重构代码时,在接下来的三个月中您将不再提供功能。不要这样做!相反,这意味着您将采用“童子军规则”,并以比签出时更干净的方式检查每个模块。

从迭代到迭代,以及从发行版到发行版,您将在继续添加新功能的同时清理该系统。没有其他办法了。”


2

您可能会向经理解释,由于代码库混乱,应花费数小时才能解决的修复工作可能要花费数天。如果其他开发人员是原始开发人员,他们将不需要重构-他们将完全了解系统,但是如果这些开发人员离开并随身携带他们的知识,管理层应该知道那里存在风险。

进行完整的重构通常是不可行的,因此经常一次重构少量位-几种方法或模块。哎呀,如果要花几天的时间进行修复,也许您可​​以同时对问题模块进行少量重构。


1
我同意-过去我只是为了理解代码而包括了这些“小的”重构,但是通常有人会“已经完全破坏了它”并将其还原为原来的样子...
billy.bob 2011年

@ m.edmondson:啊。好吧,如果他们有一套全面的单元测试套件,那么只需运行即可验证重构是否良好。从表面上看,他们没有,所以您必须自己编写单元测试。我知道这并不容易,也没有针对该问题的真正明确答案(至少我没有找到一个答案,尽管我也会一直在观察其他人的建议)。
FrustratedWithFormsDesigner

2

您是否真的需要花费数月的时间来重构代码?或者您可以在进行更改时重构代码。因此,例如,如果您确定需要修改Foo方法,则可以借此机会重构Foo方法。而且,如果您必须通过其他十二种方法来确定Foo是问题所在,则可以在这些方法中留下注释,以便您或将来的其他人知道代码应该做什么。当然,这意味着仍然存在大量的意大利面条式代码,但是您至少可以沿正确的方向移动代码库,并使自己下线更容易。花费数月的时间来重构代码将是一个大卖点,因为这意味着您在整个时间内都无法交付最终用户想要的任何东西。

创建单元测试(或希望扩展现有的测试套件)应该可以减少您无意间破坏某些内容的可能性。


0

另一个提示。当虫子出现并用绷带包扎后,不要就此止步!

问问这五个原因,服用红色药丸,看看兔子的洞有多深,并找出根本原因(及其下的路径)。

您会学到很多有关系统的知识。它有助于确定修复和重构的优先级。经过几次这样的行程后,您将获得一些坚固的“支撑梁”,以加强意大利面条的整体堆积。


0

您也可以保留旧代码,直到完全确定您的修改是可靠的为止。只是在所有情况下都可以,因此您可以在运行时切换它们,并快速查明新回归错误的位置:

// old code
...

if (!File.ReadAllText("c:\patch_control.txt").Contains("StrangeUIBugFix=0"))
{
    // new code goes here
    ...
}

// old + new code
int someValue = 
    IsEnabled("StrangeUIBugFix") ? a + b :  // new code
    a * b; // old code

0

一样东西: Never change any existing code if you are not sure what effect change would have on complete application.

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.