乔尔·斯波斯基(Joel Spolsky)在他的一篇著名文章中说:
任何软件公司都会犯的最严重的战略错误:从头开始重写代码。
乍得·福勒写道:
您已经看过视频,博客文章和炒作,并且决定将在Rails(或Java,.NET或Erlang等)中重新实现产品。
谨防。这是比您期望的更长,更难,更容易出现故障的路径。
您是否曾经参与过BIG Rewrite?
我对您在这个悲剧性主题方面的经验特别是对成功完成的任何大重写(如果有)感兴趣,都感兴趣。
乔尔·斯波斯基(Joel Spolsky)在他的一篇著名文章中说:
任何软件公司都会犯的最严重的战略错误:从头开始重写代码。
乍得·福勒写道:
您已经看过视频,博客文章和炒作,并且决定将在Rails(或Java,.NET或Erlang等)中重新实现产品。
谨防。这是比您期望的更长,更难,更容易出现故障的路径。
您是否曾经参与过BIG Rewrite?
我对您在这个悲剧性主题方面的经验特别是对成功完成的任何大重写(如果有)感兴趣,都感兴趣。
Answers:
在我的职业生涯中,我参与了一些重写工作,这些都是灾难。我认为它们都因相同的原因而失败
如果正确确定范围,则重写将非常成功。我不知道这些项目是否满足您的“ BIG”(TM)项目的门槛,但让我向您介绍一些更成功的重写。
项目1
我在公司工作了用于生成你从一种叫做零售货架上看到标签的架子带印刷系统的货架。货架图是在行业标准软件中生成的,我们的工具会读取该文档以使用目标商店的模板创建货架条。模板软件与嵌套的有限状态机混杂在一起,该状态机跨越了几个类和3个DLL。当需要实施(当时)正在申请专利的方法来制作钉板时,很明显,当前代码无法支持我们想要做的事情。
解决方案:我们将重写范围仅限于模板引擎。我们使用适当的OO设计来满足当前要求,并满足新的钉板要求。重写时间为1个月。如果我们对整个工具链进行大规模的重写,那将花费一年多的时间,但是我们不需要这样做。
项目二
我们的团队从头开始构建的Web应用程序已开始超出其原始设计。我们的客户还有一系列新要求,这些条件将使网站对我们的用户更好,如果您愿意的话,将更符合“ Web 2.0”。尽管我们可以将现有设计塞入当前的框架中,但维护却是一场噩梦。我们非常了解应用程序,我们知道必须提出哪些部分以及哪些部分将作为新版本的一部分消失。
解决方案: 我们的团队花了3个月的时间才完成–这不是一件小事。最终产品更快,更具可扩展性,并且对于最终用户而言更有趣。我们超越了客户的期望。也就是说,我们必须拆分团队,以便在现有系统上完成更直接的错误修复和创可贴补丁,而另一半在新系统上工作。我们已经进行了广泛的测试,并在流程的早期进行了整合。取得如此出色的原因是因为我们非常了解此应用程序和我们的客户。
项目3
我必须在这里包括一个失败。我们正在为需要在灾难/危机情况下使用信息管理工具的客户提供支持。我们继承了原始开发人员在没有真正了解Swing的情况下编写的Java Swing应用程序。我的意思是说,他们没有遵循Sun的建议来正确处理Swing和正确管理UI,因此您将陷入无限事件循环以及其他奇怪且难以跟踪的问题。结果,它充满了错误,用户界面问题等。这是一个非常复杂的应用程序。为了保持我们的理智,我们尝试将编写较差的Swing应用程序重写为编写良好的Swing应用程序。
解决方案:我们估计在3个月内完成了大约4.5个月的重写。该应用程序在UI和可处理的数据量方面均表现更好。然后,2004年发生了海啸。他们必须跟踪的人数之多表明,Swing是满足他们实际需求的错误技术。我们无法跟上性能调整的步伐,他们最终放弃了该工具,转而使用由他们内部的Oracle团队创建的,拼凑在一起的Web应用程序。当然,我们可以根据当时的知识来证明我们所做的事情是正确的,但是重写工作还不够积极,并且我们未能告知客户他们对可能需要跟踪的人员数量的要求也太高了低。
结论
重写有时是必要的,并且如果正确计划,它们可以成功完成。您可以针对系统的某些部分进行有针对性的重写,而不是进行整体重写。最后,导致项目失败的原因不一定是重写本身。尽管我们永远不能千篇一律,但我们可以提出一些最坏的情况。我学会了设计系统,以支持我能想到的最坏情况的两倍。就危机管理系统而言,这还不够-实际数字是我们给出的最坏情况的20倍。但这不是我们能想到的最坏情况。
我参与了从VB6到.NET的几次重写。在2种情况下,重写工作进展顺利,实际上我们提前完成了任务。另一个重写确实比预期花费了更长的时间,但是没有任何重大问题。
在我们的特定情况下,重新写入并不是我们公司可能做出的最糟糕的决定。最终结果实际上比原始结果稳定得多,并且使我们处于更好的位置。
对现有系统进行完全重写时,最大的陷阱之一就是认为“我们无需指定新系统必须执行的操作-这很简单,它只需要完全执行旧系统的操作即可!” 。
问题在于,很可能没人会确切地知道旧系统的功能,并且您将花费大量时间根据旧系统的不同用户认为它应该工作的方式来使新系统工作。旧系统的原始要求也很可能不可用。
我的是一个“成功”的故事。我的项目涉及一个具有4个独立管理/编写的卫星站点(其中具有不同应用程序的子域)的主站点。我们有4个主要用户群(均位于单独的活动目录中),并且没有一个通用的身份验证系统。其中3个是成熟的应用程序,也是筒仓式应用程序,第4颗卫星是全新的,并已从我们最成熟的站点复制了许多代码库。
目标:实施一个企业范围的身份系统,该系统可以对4个域中的帐户进行身份验证,并在其中一个域中完全管理(使用自助服务)帐户。由于.Net已经在卫星上实现,因此需要重写充当“导入”功能的经典asp网站,添加身份管理,并且所有网站都需要进行回归测试以确保不影响任何服务。
资源: 3位主要架构师-程序员,身份管理,项目经理。大约20位开发人员,10位分析师,10位测试人员。
完成时间(开始完成): 1.5年
发射成功:几乎失败
长寿成功:了不起
我是身份管理架构师,所以我设计了所有卫星之间进行交互的数据库,子系统和逻辑接口。“程序员”架构师是一位首席开发人员,对所有卫星都有广泛的业务知识,并且在应用程序及其开发方面一直积累了经验。
经过与公司各个部门的大约50位不同人员的几个月的需求收集之后,我们设法解决了逻辑体系结构,并开始编写代码。由于更改的性质,我们不得不重写我们自己的网站及其包含在.Net中的所有功能。在某些情况下,这只是重构的问题。在许多情况下,它涉及对其周围过程的完全重写。在2种情况下,我们只是简单地放弃了原始功能,因为它并不重要。在此过程中,我们错过了2个截止日期(但最终没有达到我最初建议的截止日期-几乎没有)。在发布当天没有任何效果。我们是在星期六启动的,因此影响很小,但是我整天都在梳理日志,重写代码并评估服务器负载。更多测试可能有所帮助。
到第一天结束时,所有站点都已启动并运行,并且一切都正常(我想说是成功的)。在过去的2.5年中,一切都取得了巨大的成功。将我们所有的站点都放在具有通用框架基础的通用架构上,这使开发和跨开发人员的工作变得更加容易。自从2.5年前(在重写过程中)我写到我们网站上的功能以来,几个卫星发射井就已经看到/采用了这些功能。
我们增加了日志记录,用户跟踪,增加了正常运行时间,以及负责身份验证/授权/识别的单个应用程序。卫星孤岛可以完全专注于其应用程序,并且可以相信身份管理应用程序存在任何身份验证/授权问题。
我们的项目充满了挫败感,心痛和灾难。最后,它还清了一些。我100%同意Joel Spolsky对改写的评估作为一般规则,但是总是有例外。如果您正在考虑进行重写,则只需要确保它绝对是您所需要的即可。如果是这样,请为随之而来的所有疼痛做好准备。
我现在正在参与一个巨大的代码重写中……唯一的问题是我是唯一正在处理它的人!我们当前软件的维护成本令人难以置信,它有很多错误,并且我们只有1名FT员工进行维护,因此我们决定构建自己的软件。
它比我预期的要慢得多,但最终我认为它将好得多,因为我们将拥有自己的代码库,因此可以轻松实现他们将来想要的任何更改(软件需要经常更改以跟上当前时间)。此外,我们在重写设计时对设计进行了一些重大更改。
我参与了上一份工作的完全重写。我们对此感到非常高兴。我们只是说有时候代码库太烂了,最好重新开始。
实际上,它是一个内部应用程序-主要业务应用程序。
我们在编写版本2时维护了旧系统。如果我没记错的话,我们花了大约一年的时间(两个程序员,然后是第三位)。但是,我们不需要接触数据库,因此至少数据迁移不是问题。
一切取决于。就我而言,我听从了Joel Spolsky的建议,但我错了。这是关于一个保险网站。该网站太可怕了,这是我所做的,然后是我应该做的:
不好的策略:我督导了一个由4个学生组成的小组,他们:
花了两个月的时间。然后,我们重新设计了站点。然后,我们将它设为多语言。总而言之,我们必须保留大部分糟糕的代码,并且数据库结构保持不变。因此,我现在仍在研究糟糕的东西一年,直到决定完全重写之前,它永远不会完成,这实际上是不会发生的。
好的策略:
这将花费的时间:两个月(可能更少)。
所以,我的最后一句话:这完全取决于您必须重写的内容的复杂性。
请毫不犹豫地改正我的帖子,使其英文正确,非常感谢
奥利维尔·庞斯(Olivier Pons)
在过去三年中,我一直在进行大量重写。我们最初估计该项目需要2年。基本思想是更换硬件,使用现有的操作系统,重写业务逻辑(从c到CPP),创建新的IO卡并编写新的UI。
一路上,我们做出了一些糟糕的决定。我们没有CPP的实际经验,也没有指导老师教好它。我们尝试基于win32构建自己的UI框架。硬件价格便宜,BSP有缺陷。该软件超级灵活,但难以维护。去年,我们放弃了自行开发的UI,并在.net中开发了一个UI。我们还完全重写了我们的持久性机制和数据通信协议。
花费了很多额外的精力,但是现在该项目已接近完成,并且第一批单元已在现场进行了测试。该项目冒着很大的风险要成功进行任何更改。该项目有一些积极的方面,我们开始使用SVN(而不是VSS),花了一些时间编写单元测试并实施了每晚构建。我们也开始使用scrum来改善流程。
回想起来,我认为没有必要重写业务逻辑,我们只应该重构了最丑陋的部分。对于从头开始编写UI,除非它是您的核心业务,否则不要这样做。
实际上,我正在开始一个大的重构。4MLocs应该缩小到800KLocs或更小。该项目具有大量的复制和粘贴,误解的语言功能,大量的重复无用的注释,糟糕的决定,暂时的黑客攻击,以及更多的黑客攻击变成永久性攻击(包括变通办法),对计算机科学或软件工程的基本原理完全缺乏知识。重构后,可能由32位优秀程序员的维护团队将替换为2位优秀程序员。
我在3周内写了一个博客引擎。我在8个小时内重写了它。
提前计划是 成功重写的关键。了解内部和外部系统也有好处。