专栏名称: 互联网后端架构
主要介绍Java后端架构。其中也会掺杂一些前端、GO、Python、Linux,目标:全栈工程师!---好像很牛叉的样子 ^-^
目录
相关文章推荐
51好读  ›  专栏  ›  互联网后端架构

程序员遇到祖传代码:技术债是推翻还是维护?

互联网后端架构  · 公众号  · 架构  · 2019-08-07 09:00

正文

你在写技术资产还是技术债务?

技术债务是由 Ward Cunningham 在 1992 年的报告中创造的比喻,被定义为当我们有意或无意地做了错误的或不理想的技术决策所累积的债务。简单来说就是为了快速解决问题而采取的不规范方案,比如开发工程师将某个判断条件写死、测试工程师未进行深入自动化测试、架构师运用了一个即将过时的框架。

对任何一家公司而言,在不断发展的过程中会出现很多“技术遗产”,这其中的部分遗产没有文档,甚至连注释都语焉不详,一旦引入新的需求和框架就可能出现混乱、冲突等,这部分代码很难将其称之为“技术资产”,称作“技术债务”会更加准确。

在知乎上,同样聚集了很多工程师对这一问题发表看法,比如:

写代码不写文档和测试用例,写出来的代码就不是资产,而是技术债务。

开发人员的工作比较多面,一方面开发新的需求,另一方面又要维护他人遗留代码。

作为运维,技术债务让我每天需要进行频繁的 BUG 修复上线

传统观点认为,工程技术团队应该为代码库(也就是技术债务的所处环境)建立一种直观的感受,了解其对公司的影响,而后在组织内建立信任。如果首席架构师强调重构核心代码,那么,开发者通常就得按照指示行动。诚然,如果公司可以对技术债务建立起一种共识与信任文化,这将有利于挽留优秀的工程师,并保持业务良好运作,但这往往需要多年努力。

重构 or 维护,这是一个问题?

即便技术债务让很多开发人员不爽,但是要想明白完全推翻还是继续维护,依旧是一个巨大的难题,这既需要考虑现有业务的稳定性、也要平衡后续的开发和维护成本。通常,如果业务可以正常有序的运行,管理者很难主动提出重构整个代码。但是,如果不对技术债务进行妥善管理及合理规划,组织或者开发人员很可能会陷入崩溃。

重构,就是在不改变外部行为的前提下,有条不紊地改善代码。为了保障软件的外部行为,唯一的办法就是通过测试。因此,重构是建立在完备的测试覆盖基础之上的。如果不能保证修改后的代码还能提供相同的功能,那么这种修改就可能是错误的,会给用户带来极大损失。在有风险意识的团队中,不会同意盲目重构。

即便公司有完备的测试,但如果重构花费时间周期太长,还是很危险,开发人员不得不在这段时间内同时应付重构工作和新功能的开发。框架迁移就是一个典型的例子,如果打算把旧框架的功能迁移到新框架,那么几乎所有功能都得在新框架下重新开发并测试一遍,新需求也不得不在旧框架中完成,并且最终还得再迁移过去。

所以,组织应该如何进行抉择呢?这里可以参考谷歌公司站点可靠性的例子,谷歌的搜索引擎其实并不追求 100% 正常运行。这是因为,99.99% 的正常运行足以让用户把谷歌评为“极其可靠”的服务提供者,而由于最后 0.01% 的指标太难达到,所以根本就不值得为其浪费时间。

因此,如果每年有 52 分钟的计划内停机时间,谷歌会尽可能实现这一目标。而低于 52 分钟的目标都是在浪费时间,相关成本太高,包括无法承担额外风险以及不能为客户额外提供更多功能。

如果将技术债务预算类比成站点可靠性预算,假设目前正在承担的技术债务非常关键,而且开发人员很清楚其能力低于客户与业务能够承受的最低标准,那么应该尽可能弥补,如果预算不允许,可以先考虑偿还其中一部分。如果预算充足,则可以上调风险与债务比例。

总而言之,目标是尽可能保持技术债务水平接近理想程度。换句话说,如果处于上图的红色峰值部分,那么理想的技术债务预算应该是 A 到 B。如果处于绿色峰值部分,那么理想的预算则为 B 到 C,尽量不要选择 A 到 C,这样的预算额度太过激进。

AngelList 公司的 Andreas Klinger 曾在文章中提到:

“很多东西其实没有必要重构。如果其并不关键,或者未来几个月内并不需要改进其功能,又或者其太过复杂,那么将其纳入技术债务即可。”

简而言之,应该首先确定需要在本周、本月或者本季度完成的目标,与其存在技术债务的代码库之间的交集,只偿还交集之内的债务,其它的以后再说。除了重构,团队也可以选择将非核心技术栈外包出去,转交给更合适的团队。需要注意的是技术负债具有利滚利效应,偿还周期越长,所需偿还的债务总量就越多。

如何避免过度浪费时间?

即便是技术债务,现在也有很多指标可以帮助量化分析,避免过度浪费时间。决策者可以利用数据分析快速确定需要尽快偿还哪些技术债务,比如:

  • 识别代码库中归属关系较弱的文件,因为代码归属权是代码库运行状况的主要指标。

  • 衡量文件的内聚与耦合情况,并最终列出一份包含弱归属权、低内聚与高耦合文件的列表。

  • 计算各个文件的组成以确定问题文件中的各个子集。正如微软研究院所指出,“活动文件仅占系统总体大小的 2% 至 8%,但占系统文件变更的 20% 至 40%,而且有 60% 到 90% 的 bug 来自于此。”

  • 将这些文件与本季度的发展路线图进行比较。在路线图当中列出的所有功能,是否都要求工程师对问题文件子集进行调整?如果答案是肯定的,请将这些文件作为重构对象,估算相关工作量,并将其分配给文件所有者的工程师。最后,把这部分工作量纳入下阶段计划。

国内技术从业者怎么看?

针对这一问题,InfoQ 采访了国内一些技术从业者,针对技术债务的判断原则、分类、应该采取哪些措施以及如何避免在技术债务上浪费过多时间等问题进行了交流。

刘译璟,百分点 CTO

技术债是指在软件工程中“应该”做而“没有”做的那些事情,简单说就是没有兑现的那些承诺。在软件工程的各个环节都有可能存在负债,包括:需求分析、方案设计、架构设计(逻辑架构、功能架构、数据架构、部署架构、运行架构等等)、编码、测试、发布,以及整个软件工程的流程都有可能是存在不合理的、负债的。







请到「今天看啥」查看全文