是否有关于重写软件成功/失败率的实际案例研究?


36

我已经看到多篇关于应用程序重写的文章,这些都是不好的,人们在Programmers上的经历,以及Joel Spolsky编写的关于该主题的文章,但没有确凿的证据或案例研究。除了Joel给出的两个示例以及此处的其他一些帖子外,您如何处理不好的代码库,以及如何根据实际研究决定如何处理它?

就目前的情况而言,我知道有两个客户端都具有旧的遗留代码。他们一直之以鼻,因为正如其中之一发现的那样,重写是一场灾难,这很昂贵,而且实际上并不能有效地改善代码。随着重写者迅速发现,该客户具有一些非常复杂的业务逻辑。

在这两种情况下,这些都是关键任务应用程序,可为公司带来大量收入。试图重写的人认为,如果将来某个时候不对旧版软件进行升级,它们将陷入困境。对我来说,这种风险需要进行研究和分析,以确保成功的道路。

是否有实际的案例研究对此进行了调查?我不希望尝试大量重写,而无需根据实际研究了解一些最佳实践,陷阱和成功。

后果: 好的,经过更多搜索,我确实找到了三篇有关案例研究的有趣文章:

  1. 重写或重用。他们对转换为Java的Cobol应用程序进行了研究。
  2. 另一个是关于软件重用:开发人员的经验和看法
  3. 重用或重写关于维护与重写成本的另一项研究。

我最近找到了另一篇有关该主题的文章:The Great Rewrite。在那儿,作者似乎遇到了一些主要问题。随之而来的是通过使用建议的新技术堆栈并测量开发人员将其拿起的速度来进行原型制作的想法。这全都是重写的序幕,我认为这是个好主意!


10
我不了解案例研究,但我认为该方法的标准答案可能是“添加单元测试和重构”。
杰里·科芬

2
它给我留下了很可能是最低风险的方法。当然,我不知道足够的细节来确定这是正确的方法,但是根据我到目前为止所知道的,我不知道有什么特别好得多的东西。
杰里·科芬

2
如果他们进行单元测试(正确地-真正捕获所有需求),则很难想出一种重构方法来导致真正的灾难。可能发生的最糟糕的情况是,您的进度没有您想要的那么快。同时,如果他们的代码库的形状像问题所暗示的那样糟糕,那么很可能需要付出很大的努力才能实现进度,而与采取的路线无关。
杰里·科芬

2
如此众多的项目都是私人的,因此很难为一个研究提供一个非常好的样本集。您可能仅限于轶事证据。
mike30 2012年

1
问题不在于重写整个代码库。问题是要一次重写整个该死的东西,然后按一个按钮,然后消除所有的头痛。在大多数情况下,您无法承受失去竞争对手增加新功能,让bug恶化,让客户取消的时间。无论代码库有多大的灾难,您都应该有可能找出痛点,并在进行过程中模块化合适的意大利面条。
Erik Reppen

Answers:


6

我不能赞扬这些出色的评论,但是原始作者从未将它们给予答复,因此我将其标记为社区Wiki。

我不了解案例研究,但我认为该方法的标准答案可能是“添加单元测试和重构”。

它给我留下了很可能是最低风险的方法。当然,我不知道足够的细节来确定这是正确的方法,但是根据我到目前为止所知道的,我不知道有什么特别有可能变得更好。

如果他们进行单元测试(正确地-真正捕获所有需求),则很难想出一种重构方法来导致真正的灾难。可能发生的最糟糕的情况是,您的进度没有您想要的那么快。同时,如果他们的代码库的形状像问题所暗示的那样糟糕,那么很可能需要付出很大的努力才能实现进度,而无论采取哪种方法。

我认为重写项目的失败率与一般项目没有显着差异,并且可以参考最新的CHAOS报告以获得最佳信息。


8
通常,需要重写的代码以无法测试的方式(紧密耦合,类做得太多等)编写,这使您处于在进行单元测试之前需要重构的奇怪位置。
凯文(Kevin)

是的,这就是为什么对这本书的评论“有效地使用旧版代码”非常恰当的原因。去年,我不得不做类似的事情,并且采用一种更系统的方法,如那本书中所解释的,这可以为我节省很多时间,并且留下了有用的文档/测试线索。我觉得让它正常工作是很棒的,但是还不够。这些对象具有如此多的依赖关系,我觉得我的测试本来可以覆盖得更好。

6

不久前,我浏览了Michael Feathers《有效处理旧版代码》,发现它为维护旧版代码的实际实践提供了一些很好的见解,包括编写测试(即使您不知道代码的用途)以及课程重构/重写。它有点陈旧,但在亚马逊上获得很高的评价。


3

从经验上讲,并从一开始就在企业架构方面构想不佳的公司中生活,我可以诚实地说,最大的问题是建立全面的了解。

可以将系统分解成各个部分并分别理解的想法是有缺陷的。在某个时间点,一个人或几个人必须能够完整地理解整个问题。如果那个问题是一系列业务问题和驱动它们的技术;公司中的人员可能需要花费几年的时间才能理解所有系统,以至于可以在不造成灾难或遗漏要求的情况下更换它们。当我接任技术总监时,在我公司当然就是这种情况。如果不是因为我自己是一名编码人员,那么我将无法慢慢理解组织不良,紧密耦合,紧密绑定的体系结构和技术集成的所有细节。如果有小的隐藏的,未记录的细节,例如"We put the eBay order number in the "SYSOENT.PO_NUMBER" field in the ERP system because that's what Wendell the VB coder from Florida decided to do" 被忽视的结果可能是灾难性的,唯一了解这一点的方法就是慢慢发现所有这些。

如果要求某人在飞行中更换飞机上的发动机或面临某种死亡-鉴于个人需要掌握适当数量的工具和资源,他们将需要知道如何超越传感器,液压系统,如何重新安排燃油流量,操纵从未设计过可在外部或从驾驶舱进行更改或操纵的系统。这通常是重写业务应用程序的前景。该应用程序通常在许多其他技术之间介入业务。

我想我的主要观点是,必须以几乎完全的复杂性来理解该系统,并且必须在某个时间点上以完整性来理解该系统,以便正确地对“新系统”进行“设计”,而不仅仅是“制造”。

制作Cookies,(应)设计软件。


2
+1是因为需要提前了解很多业务系统。但是,如您所知,这里面临的挑战是时间和资源(来自企业)以及变化因素。对于中型和大型系统,有时并不总是可能预先了解全部复杂性。
NoChance 2012年

2

有许多因重写而死的公司的例子,例如Netscape。还有一些公司在重写过程幸免于难,而没有像Twitter这样的大麻烦

没有任何量化的案例研究,因为进行对照实验来观察不重写的业务成功与重写的业务成功是不可行的。每个应用程序都是不同的。

在某些明显的情况下,重写有意义,而在许多情况下却没有意义。我已经准备了一个小菜谱,弄清楚重写是否适合您的情况。

我认为,如今的重写更有意义,因为我们正在不断改进诸如Rails,Grails和AngularJS之类的侵入性框架,从而迅速进行编码。如果您想从普通js迁移到Angular,则可以做很多重写。这可能仍然很有意义。如果要用另一种diy实现代替另一种diy实现(例如Joel Spolsky文章中的所有示例),您可能会疯了。


1

除了行动报告之后,您不会找到许多无偏见的案例研究-大多数人不会为完成相同的工作至少两次而付费(一次重写,一次升级,最好案例是不同团队进行多次重写/升级)。

您发现的案例研究似乎是由Fujitsu制作的,毫不奇怪,结果是使用Fujitsu的工具更好。

从组织的角度来看,仅当重写的应用程序不起作用或项目在完成之前被取消时,重写才显然是失败的;否则,无法知道发布重写版本的延迟是否是失败的原因。您遭受的任何损失或仅仅是偶然的原因。如果在完成之前取消,则通常被视为浪费时间和资源。升级可能会遇到相同的问题,但是增量式升级不可能达到相同的规模(您会得到一些钱)。

从编程的角度来看,最好的情况是两者都做-在重写的同时进行增量升级,互相支持并相互启发。除非您拥有不同的团队,否则这自然会花费更长的时间。

请注意,这为您应该考虑进行整体重写提供了一个粗略的指导原则-项目足够小,您可以轻松地完成;或者组织的规模足够大,可以承担全部工作,计算工作量或学习成本值得。还要注意,如果重写永远无法赶上重做,这可能意味着几件事情,但在其他所有条件相同的情况下,则可能意味着不需要进行重写。


1
如果重写工作超出预算,并且在完成之前被取消,则重写可能会失败。钱花光了。这种可能性的可能性是为什么重写被认为比重构更危险。
MarkJ 2012年

@MarkJ:我以为“不起作用”已涵盖了该内容,但我将对其进行编辑以使其更加清晰。
jmoreno'3
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.