当前位置: 首页 > 科技观察

代码重构的那些坑和实战经验

时间:2023-03-12 18:06:38 科技观察

2016年冬天,我在一家创业公司的小团队里从事软件开发。当时我们有一个真正的企业客户,软件的第一个版本已经发布。开发如期进行,发布时我欣喜若狂,看到系统每天为数百万独立用户提供服务并发送数千万条短信,我感到非常满意。到第二年夏天,公司赚到了真钱,我的角色变成了开发主管,公司招了一些新人,生意兴隆,一切都很好。然后我们犯了一个大错误:我们决定从头开始重写软件。为什么我们觉得有必要从头开始重写软件?刚开始写系统代码的时候,我们的工期很紧,要争分夺秒地赶工期。因此,设计讨论和审查会议都没有花太长时间——我们没有时间可以浪费——只是匆匆忙忙地完成一个功能,快速测试它,然后赶到下一个。我们与其他公司共享办公空间,我记得其他公司的软件开发人员会花很长时间进行设计,讨论架构,然后花数周时间讨论设计模型。除了仓促设计外,原来的系统写得还不错,整体架构还不错。一些意大利面条式的代码是公司之前的概念验证遗留下来的。因为这些代码是可以用的,而且时间紧,所以当时没有去碰。但后来我们没有考虑进行优化改进,而是决定从头重写代码,因为:旧代码不好,难以维护;百万移动用户和多站点部署的大型运营商;我想尝试很酷的新技术,比如ApacheCassandra、虚拟化、二进制协议、SOA等。结果很不幸:我们说服了整个公司和董事会,愿望成真了。代码改写之旅的正式开发时间是从2016年春季开始,我们将2017年1月下旬定为发布时间。由于项目太大,我们需要更多的人,所以我们在印度聘请了顾问和一些远程开发人员。然而,我们并没有完全预料到维护遗留系统、进行新的开发工作和了解客户需求的并行工作量。还记得我在文章开头说过,我们有真正的客户吗?该客户是南美洲最大的移动运营商之一。我们开发的系统上线后,他们开始要求更改和新功能,因此我们不得不不断更新旧系统。但是,由于这个系统将被废弃,我们在更新的时候总是有些敷衍,并且找借口拒绝了很多客户提出的新功能要求。致使工期延误,无法在原定期限内完成进度。事实上,我们的进度延迟了整整8个月。不过还是先说说结果吧:当项目最终完成的时候,新系统看起来很棒,满足了所有需求。我们做了负载测试,结果显示新系统可以轻松支撑1亿多用户,配置集中,查看图表的UI工具也很漂亮。是时候放弃旧系统,换上新系统了。。。但是客户拒绝升级要求:原系统已经得到广泛使用,他们的用户已经开始依赖旧系统,他们不不想冒任何风险。长话短说,在浪费了几个月之后,我们收效甚微。该项目被正式宣布失败。当你需要重写代码时JoelSpolsky强烈反对重写代码,他建议大家不要这样做。但我不是特别同意:有时增量优化和重构是如此困难,以至于理解代码的唯一方法就是重写它。软件开发人员也喜欢编写代码和创造新事物——阅读别人的代码并试图理解他们的代码和“抽象思维”可能会很无聊。然而,优秀的程序员也是优秀的维护者。如果您想重写代码,请出于正确的原因并按照正确的计划进行。例如:有时候新版本发布很久之后,旧代码仍然需要维护。维护两个版本的代码需要大量工作。在开始重写之前,请根据项目规模评估所需的时间和资源。想想其他失去的机会并比较任务的优先级。重写大型系统比小型系统风险更大,请考虑是否可以逐步完成。我们同时做了几件事:切换到新数据库、使用“SOA”架构、更改为二进制协议,我们本可以逐步完成这些更改。考虑开发者偏见。当开发人员想要学习新技术或语言时,他们会想用这些来重写一些代码。不过我并不反对,这也是良好环境和文化的标志,但它应该与风险和机遇相提并论。迈克尔·梅多斯(MichaelMeadows)对何时需要“重大”重写有很好的看法:从技术上讲,组件是如此耦合,以至于无法修改单个组件。重新设计单个组件会导致一连串的更改,不仅会影响相邻组件,还会间接影响所有组件。技术栈过于复杂,未来状态设计需要大量的基础设施变更。出于这个原因,执行完全重写是必要的,在这种情况下,逐步重新设计没有优势。重新设计单个组件无论如何都会导致对该组件进行重写,现有设计中没有可以插入新功能的地方。在这种情况下,逐步重新设计没有任何优势。政策发起人未能理解渐进式重新设计需要对项目的长期承诺。不可避免的是:大多数公司没有兴趣继续在增量重新设计上浪费预算。这种现象在完全重写代码的情况下也很难避免,但发起人更愿意继续投入,因为他们不想使用半成品的新系统和部分过时的旧系统。系统用户更习惯于使用“原生界面”:在这种情况下,政策不允许修改系统的重要部分(前端)。但是如果完全从头重写,这个问题就会被绕过。用户仍然会坚持使用“相同的界面”,但这一次你有更多的理由反击。请记住:逐步重新设计的总成本总是高于完全重写代码,但通常对业务的影响较小。在我看来,如果有充分的理由重写,并且公司有超级优秀的开发人员,那就开始工作吧。放弃正在开发的项目是危险的:大量时间和金钱被浪费在重新实现现有功能上,同时放弃实现新功能的机会,这可能会激怒客户并延迟工作进度。如果您正在重写代码,那是您的权利,但请确保您出于正确的原因这样做,了解风险并为此做好计划。