20

只是想听听一些建议(和安慰..),这将帮助我控制一些复杂的意大利面条代码——由多个程序员(通常从不见面)长时间开发的代码。该解决方案的功能只是相互叠加。

通常我倾向于看到两种程序员:

  1. “吓死程序员”——那些人不会碰任何他们不需要的东西。他们可能会使用快速而肮脏的修复来完成维护任务,这将使下一个程序员开始寻找他们的家庭地址;-)

    优点:
    有效

    缺点:
    你希望你永远不会再看到这段代码。

  2. “教师”——他们可能会重写整个代码,同时完全翻新其逻辑。

    优点:
    嗯,总得有人干脏活……

    缺点:
    需要更长的时间,并且可能最关键的功能之一会神奇地从产品中消失

很高兴听到您从程序员生活的阴暗面听到您的个人经历。

我特别想听到任何理论/实践建议,这些建议将帮助我深入研究意大利面维护任务而不会感到如此悲惨。

4

15 回答 15

21

在开始之前,我尝试将非常糟糕的遗留代码包装在测试中。老实说,我几乎在测试中扼杀了它!然后我有信心在需要的地方进行重构。

你可能喜欢阅读

封面

有效地使用遗留代码

于 2009-04-02T21:41:11.797 回答
18

虽然最好的建议是,正如其他关于该主题的海报所指出的那样,编写测试,但我经常处于不切实际的情况。如果代码那么糟糕(1000 行方法、嵌入和未记录的幻数、代码重复等),它还可能存在另一个问题,即它是深度耦合的,组件几乎不可能隔离。

(例子

  • 一个在启动时加载和缓存数百个不同数据库对象的代码库。组件假设缓存的随机部分存在,部分缓存假设缓存的其他部分 - 换句话说,您必须加载整个东西才能获得任何东西
  • 代码依赖于静态的、混杂的公共状态变量,无法确定谁在设置这些变量,甚至无法确定它们的含义)

我能提出的最佳建议:

  • 尝试先解决简单/显而易见的事情。硬编码路径、幻数引用、明显的代码重复。也许摆脱最严重的 20% 违规行为的快速发布将是低风险的,并使后续步骤更容易完成。
  • 获得组织对重构的支持——通常没有意愿或愿望去做不立即添加功能的工作,并且有破坏现有代码的风险。当然,重构有很好的论据,但并不是每个人都购买它们。如果组织不支持它,您可能不得不放弃它。
  • 让其他开发人员也有同样的看法——如果他们做得好,他们可能和你一样对代码库不满意。如果新代码按照更好的标准构建并且人们受到激励,他们将开始修复旧代码,因为需要应用调整。
  • 如果一个特定的子系统真的非常糟糕,并且已经到了几乎不可能进行新开发的地步,您可能可以利用这个机会来重建它。
于 2009-04-02T21:59:47.353 回答
9

文档。彻底记录。你所做的每一个改变——你发现的每一个警告,你追踪的每一个奇怪的逻辑流程,每次你认为“这可以做得更好”——记录下来。

这是在不进行大量重写的情况下减慢并最终消除系统熵的唯一方法。

于 2009-04-02T21:42:02.153 回答
8

我知道的唯一方法是:

  1. 编写测试
  2. 重构
  3. 运行测试
  4. 修复损坏的东西
  5. 为新功能编写测试
  6. 引入新功能
  7. 运行测试
  8. 修复损坏的东西

你可以这样度过。

注意:有时很难对意大利面条代码进行单元测试:生成 HTML 的 3Klines 方法、与业务逻辑纠缠的 DAO、强耦合类......开始),并且像Selenium这样的一些测试工具可能会派上用场。

于 2009-04-02T21:42:55.273 回答
5

两全其美。将您的项目组织成逻辑部分,最好使用逆向工程 UML 类图,并查看互连在哪里。任何松散连接的东西都是重构的理想选择。在任何停机时间,也要检查强连接,看看哪些组可以完全拆分为单独的模块,更改最少。在重写整个事情之前,先从高层次弄清楚到底发生了什么。

于 2009-04-02T21:40:57.883 回答
4

我正在修复旧代码应用程序的错误。我尽量不抨击以前的开发人员(尤其是因为我还在学习)。我更改的所有内容都会进行广泛的评论,以便我可以再次找到它,以便下一个人了解代码是如何演变的。

永远记住,你不可能知道编写代码的所有环境。虽然这并不一定是糟糕的编程或逻辑的借口,但它肯定会让你的血压下降。

我还将遇到的每一个令人头疼的问题都视为学习和/或尝试新事物的新机会。

于 2009-04-02T21:54:16.947 回答
2

以下是我在维护一个已有 10 年历史的遗留 perl 系统的同时解决这个问题的方法。稍微介绍一下背景,这是最糟糕的情况之一。当我开始在公司工作时,我最初很沮丧,因为代码设计和布局都很糟糕(这是我的第一份编程工作)。在那场演出结束时,我有了一个非常好的系统。

首先,每个新功能都作为新模块或方法添加。在现有代码之上没有任何东西被入侵。这让我可以为新东西编写单元测试,提供对它的信心,因此与旧东西集成只是一两行的问题。

其次,任何错误修正都是以同样的方式实现的。我会花一些时间弄清楚旧的东西发生了什么(而不是寻找错误),我会将它写成一个新方法(或模块),并将它包装在测试中,然后通常可以替换.

然而,这只有在你有时间并且有能力完成它的情况下才有效。如果不这样做,请跟踪您在任何给定错误上花费的时间。尤其是在同一个文件、进程或其他任何地方存在多个错误的情况下。在某个时间点,很容易指向给定的代码集合并说这太糟糕了,已经花费了 N 时间,是时候重写了。

我通过这种方法获得了足够的成功,获得了“法医程序员”的荣誉称号,这也是一项了不起的技能,因为新工作通常已经编写了一些代码:P

于 2009-04-02T22:23:32.960 回答
2
  • 缓慢而深思熟虑。
  • 尽可能写测试,但当你不能时不要沮丧。意大利面条代码很少是可测试的代码。
  • 请记住,在您之前编辑代码的每个人都有充分的理由去做他们所做的事情。假设他们是最好的,你可能会得到回报。
  • 在尝试更改代码之前了解代码。
  • 在学习时记笔记,并在工作时保持最新状态。如果可以,请在 wiki 上保留并分享它们。
  • 使用修订控制系统,使每个更改尽可能小且集中,并尽可能频繁地检查。
  • 不要咬得比你能咀嚼的多。当您进行一项更改时,您无疑会发现应该清理的其他内容。将其添加到您的待办事项列表中,并继续专注于您最初的任务。
  • 像对待露营地一样对待这个项目:让它保持比你发现它更好的状态。请记住,“更好”是相对的;你不能一次解决所有问题。
于 2009-04-02T22:36:39.323 回答
1

吧:)

如果那不是一个选择,那么……首先,试着把它搞清楚。对于我处理过的东西,这通常是最难的部分。你可以手动创建UML,你可以使用一些商业源代码“逆向工程”工具,或者你可以只跟踪代码。

当您对代码有所了解时,就该进行重构了。计划好。试着写一堆像样的测试。然后通过重构的迭代方法,编写额外的测试,检查(工作!)修改回到源代码控制。

根据您的受虐程度,这可能很有趣,也可能是您自己的地狱:)

于 2009-04-02T21:53:15.340 回答
0

虽然我自己从未这样做过,但这种方法很有意义。围绕现有的公开接口编写大量测试,以确保在您进入并重构实现的狄更斯时功能不会改变。这将确保任何重构都不会改变应用程序的运行方式。

于 2009-04-02T21:43:37.550 回答
0

我知道在我曾经做过系统管理员的一家知名保险公司中,使用的主要定价系统是一个 25 岁的大型机,称为 GenZ。我认为,自九十年代中期以来,一个新系统一直在开发中,目前正在测试中推出

大型机可能在 1980 年代运行良好——但随着公司的发展,添加了更多数据,系统需要容纳更多数据。应用了补丁,发生了更多问题,并且多年来一直如此。

目前,该系统与该保险公司使用的至少 200 个其他应用程序交互,因此更换它将是一项非常艰巨的工作,这可能是它被推迟这么久的原因。

现在新系统(称为 Maxx)正在推出,数百个应用程序将不得不逐步淘汰。

糟糕的编码并不是因为开发人员害怕做不需要的事情,而只是因为他们没有想得足够远,没有考虑最坏的情况,或者考虑到消费者、员工可能会是什么样子和未来的开发者。

于 2009-04-02T21:49:49.360 回答
0
  1. 首先,让管理层相信改进代码对于提供业务价值是必要的(比如将来添加功能变得更容易)。我个人浪费了宝贵的时间来改进 报废申请。
  2. 彻底了解领域,某些类型的领域鼓励某些类型的(反)模式..这将有助于理解为什么事情是这样的。
  3. 围绕遗留代码编写测试有助于我探索业务逻辑中造成现在代码混乱的各种细微差别。我个人从不针对遗留代码进行测试的代码覆盖率(尽管这是一种普遍宣传的方法),它只会让你发疯。
于 2009-04-02T22:20:36.070 回答
0

好吧,我必须重构一个用 Coldfusion、javascript、html 编写的噩梦网站,并使用几个插件......我是这个应用程序的唯一开发者。最后一个维护网站和数据库的人被调走了。我被这个丑陋的野兽困住了。我确实重构了一些文件和功能,但问题和错误不断出现。

我的问题应该集中在修复错误或重构上,我想完全花时间重构而不是被拉来服务更改请求或错误。

有些文件是 8k 行,因为上一个开发人员(不是真正的开发人员)保留了复制和粘贴代码块而不是分离功能。这是一个非常紧密耦合的代码,一个文件中的一个小改动将需要在其他 4 到 5 个地方进行更改。

我建议将网站分解为可管理的小单元,然后从头开始重建。到目前为止,他们并没有真正倾听,而是一直在问为什么网站运行缓慢。

我通过从主网站(本地)拉出和测试代码来一次到达那里。

于 2009-05-19T17:36:41.290 回答
0

我发现很多时候你可以将意大利面条的块分成至少单独的源文件,有时是单独的类,而无需重写任何实际逻辑。如果您可以从一两个错误修复中抽出一些时间来完成此操作,那么您将远远领先于您的起点。

稍后,当更多的错误出现时,您可能能够更好地模块化一些东西。慢慢地,你可以用这种方式把意大利面弄直。

于 2009-05-19T18:04:24.013 回答
-1

好吧,也许这正好适合我的情况,但它是这样的:

考虑到上述所有建议,如果我要长时间处理遗留代码,我会清理脏代码,非常流畅,所以我不会破坏它,如果不我不会打扰

于 2009-04-02T21:58:26.843 回答