在第一次编写系统代码时,咱们的时间表十分紧迫,必须与时间赛跑,在计划时间内赶完进度。所以不管是设计讨论,仍是审查会议都没花太长时间——咱们没有时间浪费在这上面——只能匆匆完成一个功能、快速测试,而后赶着去作下一个。咱们与别的公司共享办公空间,我还记得其余公司的软件开发都会花很长时间作设计、讨论架构,再花上数周讨论设计模型。html
除了设计仓促,本来的系统写得不差,整体来讲架构也不错。其中有些意大利面条式的代码,是公司以前作概念验证时留下的,由于这些代码能用,再加上工期紧张,当时咱们没有去碰。但后来咱们不考虑执行优化改进,却决定要从头重写代码的缘由在于:前端
老旧代码很糟糕,很难维护;java
“单一总体式的java架构”对咱们的将来发展不利,没法支持有6千万移动用户以及多站点部署的大型运行商;程序员
我想要尝试炫酷的新技术,好比Apache Cassandra、虚拟化技术、二进制协议、SOA等等。数据库
结果很不幸:咱们说服了全公司以及董事会,实现了愿望。架构
正式的开发时间是从2012年春天开始的,咱们将2013年1月末设定为发布时间。因为计划太过庞大,咱们须要更多的人,因而在印度聘请了顾问与几个远程开发者。可是,咱们没有充分预期到维护本来系统、进行新的开发工做与理解客户需求这些并行起来的工做量。工具
还记得我在文章最开始说过,咱们有一个真实客户么?这位客户是南美最大的移动运营商之一。在咱们开发的系统投入使用后,他们开始对变动和新功能提出要求,所以咱们只能继续更新原来的系统。可是,因为这个系统将会被废弃,在更新时咱们总有些敷衍了事,尽量找借口拒绝了客户许多的新功能需求。结果致使了工期拖延,没能在原定的deadline完成进度。事实上,咱们的进度拖延了整整8个月。性能
不过咱们仍是先说说结果吧:当项目终于完工时,新系统看起来很是棒,知足全部需求。咱们作了负载测试,结果显示新系统能很容易地支持超过1亿的用户,配置集中,查看图表的UI工具也很美观,是时候废弃旧系统,改换新系统了……学习
可是客户拒绝了升级的请求:本来的系统已经得到了普遍应用,他们的用户已经开始依赖旧系统了,他们彻底不想冒风险。长话短说,浪费了几个月以后咱们收效甚微。该项目正式宣告失败。测试
大多状况下都不应从头重写代码。咱们重写代码的缘由是错误的,尽管一部分代码不怎么样,若是咱们花些时间阅读理解源代码,就能够经过重构修复问题。对架构的可扩展性及性能咱们确实有顾虑,担忧它没法支持复杂的业务逻辑,但彻底能够逐步进行修复。
从头重写系统对用户来讲没有价值。新技术与流行词对工程师团队来讲看似很酷,但若是不能按照客户需求提供新的功能,则毫无心义。
咱们在集中精力重写代码时,错过了真正的机会。之前咱们给客户提供了一个很是基本的“站点分析工具(Web Tool)”供他们查看图表与报告。但随着内容愈来愈多,他们开始要求增长新功能,好比实时图表、访问级别等等。因为咱们不打算继续沿用旧代码,时间也不足够,就敷衍着要么拒绝了新需求,要么凑合了事。结果最后客户再也不使用这个工具了,他们坚持经过邮件来发报告。原本咱们还有另外一个机会来构建一个有紧迫需求的强健分析平台。
我低估了在维护旧系统的同时,开发新系统所须要的工做量。咱们本来预计一个月能有3到5次需求,结果倒是预计数量的三倍。
咱们觉得:因为没能花上很多天讨论合适的设计模型与实例,代码就会很难阅读与维护,结果事实上我在较大公司所见过的最专业代码,比咱们的代码还要糟糕两倍。所以,在这一点上咱们大错特错。
Joel Spolsky强烈反对重写代码,他建议你们都不要这样作。不过我不是特别认同:有时候逐步优化与重构很是困难,惟一读懂代码的方式就是重写。此外软件开发人员喜欢编写代码,创造新东西——阅读别人写的代码,尝试理解他们的代码与“思惟抽象”会很无聊。不过,优秀的程序员也是优秀的维护者。
若是你想要重写代码,必定要出于正确的理由,并有着合适的计划。好比:
有时候在发布新版好久以后,老旧代码仍需维护,维护两个版本的代码须要耗费大量工做,在开始重写前请根据项目规模评估所需的时间与资源。
想一想其余失去的机会,并比较任务的优先级。
重写大型系统比小型系统风险更高,考虑一下可否逐步重写。咱们同时执行了如下几项工做:切换到新的数据库、使用“SOA”架构、更换为二进制协议,其实本能够逐步执行这些更换。
考虑开发者的偏见。在开发者想要学习新技术或新语言的时候,他们会想要使用这些来重写某些代码。不过我不反对这样作,这也是良好环境与文化的标志,但应当将它与风险和机遇作比较。
Michael Meadows对什么时候有须要进行“大型”重写有着很好的见解:
技术上
组件的耦合度很高,没法单独对某个组件进行修改。从新设计单个组件会致使一连串的变化,不只会影响到相邻的组件,甚至间接影响到全部的组件。
技术堆栈太过复杂,将来状态设计须要变动不少的基础架构。出于这个缘由执行彻底重写十分必要,逐步从新设计在这种状况下没有优点。
从新设计单个组件不管如何都会致使对该组件的重写,在现有设计中没有能够插入新功能的地方。这种状况下逐步从新设计没有优点。
政策上
赞助商没法理解逐步从新设计须要对项目进行长期投入。不可避免的是:大多数公司对于在逐步从新设计上继续耗费预算没有兴趣。在彻底重写代码时,这种现象也很难避免,但赞助商更愿意继续投入,由于他们不想用着半成品的新系统与部分过期的旧系统。
系统用户更习惯使用“本来的界面”:在这种状况下,政策上不会容许修改系统的重要部分(前端)。但若是彻底从头开始重写,则会绕过这个问题。用户还会坚持使用“相同的界面”,但此次你反击的理由更为充足。要记得:逐步从新设计的总成本老是要高于完整重写代码,但通常来讲对企业的影响更小一些。在我看来,若是重写理由充足,公司又有超级优秀的开发者,那么就开工吧。
放弃正在开发的项目很危险:浪费大量的时间和金钱重复实现已有功能,同时还会放弃实现新功能的机会,有可能激怒客户并致使工做计划推迟。若是你正在重写代码,那是你的权力,不过请确保这么作的理由正确,同时了解风险也作了相关计划。