💰 技术债 - 数字化时代的羁绊
在我们的工作经历中,都往往会与技术债打过交道。甚至被它扰乱了我们的心智。如果你目前还未有过工作经历,或者还没接触到它。这并不意味着你可以对此置身事外,因为在以后的经历中或多或少都会经历。
技术债的定义
官方解释,技术债(Technical Debt)是指在软件开发过程中,为了快速实现某个功能或解决某个问题而采用了一些不太理想的解决方案,从而导致代码质量下降、可读性变差、可维护性降低等问题。
技术债通常表现为以下几种形式:
- 代码质量差:代码中存在大量的冗余代码、重复代码、魔法数字、长函数、嵌套条件等,导致代码难以理解和维护。
- 缺乏测试:代码中缺乏足够的测试用例,导致难以保证代码的正确性和稳定性。
- 不合理的架构:采用了不合理的架构或设计模式,导致代码扩展性差、难以复用。
- 技术过时:使用了过时的技术或框架,导致代码难以维护和升级。
- 紧急修复:为了快速修复某个问题而采用了临时的解决方案,导致代码质量下降。
技术债的种类
技术债的种类大概分为以下8种:
代码质量债务、测试债、架构债、技术栈债、文档债、性能债、安全债、数据质量债
技术债的影响
顾名思义,技术债也是一种债务拖欠。也会随着时间的推移产生相应的利息。而这些债务和利息都是再后续需要偿还的。
代码质量债务
在发布的代码中存在低质量、难以理解、缺乏注释、重复代码等问题。这样的问题会严重导致可读性和可维护性差。 当项目需要进行交接转移的时候也是给下一个开发人员时,带来很大的代价。比如功能点难以梳理理解、或导致意想不到的副作用。
测试债
缺乏足够的测试覆盖,或者测试用例不完整、不准确,导致难以确保代码的正确性和稳定性。这往往会导致代码进行变更时,难以覆盖的所有场景。尤其是极端操作或者边缘性操作。会导致意料之外的bug的产生。
架构债
系统架构设计不合理,缺乏可扩展性、灵活性或可重用性,导致未来的修改和扩展变得困难。这种情况也是
技术栈债
使用过时的技术或框架,难以找到合适的开发者或获取支持,增加了项目的风险。或锁定类库的版本。
项目所依赖的类库没有及时更新补丁、采用活跃度低很久没维护的开源依赖、或者锁定类库版本都是不负责任的。这往往是在埋雷的行为。经常会出现在老项目重启的时候,发现很多已经被早已废弃,导致为研发新增很多不必要的心智负担。
文档债
缺乏或不完整的文档,包括需求文档、设计文档、用户手册等。
首先影响的是on call的同事和当前负责的开发人员和维护人员。当其余同事接触这个项目的时候,往往是会先去阅读项目对应的相关文档来寻求信息。一份不完善的文档会使理解的难度指数型增长。耗时也会成倍的增加。
其次,会影响产品的使用人员。往往每一个优秀的产品都离不开健全详细的文档。一份缺乏或不完整的文档往往会使人摸不清头脑。
性能债
系统性能低下,可能是由于算法效率低、数据库设计不合理或硬件资源限制等原因导致。这种债务前期并不容易察觉,因为初始状态下数据量往往不会太庞大。但是当推着时间的推移,数据量很有可能变得格外庞大。这种情况下,性能债就会暴露在大众视野。往往性能债会严重影响用户体验。更严重者会导致功能崩溃毫无相应。
安全债
代码中存在安全漏洞或缺乏适当的安全措施,可能导致数据泄露、恶意攻击等安全问题。安全债毋庸置疑必定是最高等级的债务。
数据质量债
指数据不准确、不完整或不一致,可能影响系统的正确性和决策的可靠性。数据质量债是一种常见的债务。它会是产品或逻辑没有以预想的方式进行,从而产生错乱的用户体验。
关于项目中现存技术债的讨论
重点放在技术债的成本和修复它所带来的好处。
第一步,需要按照事实现在描述目前的情况,说明技术债造成了哪些影响。
第二步,对本次修复技术债的技改进行评估,本次的变更需要消耗的成本是多少?变更会造成什么样的影响?影响的范围有哪些?
第三步,描述当前技术债你打算采用的第一解决方案和备选方案(不采取行动也是备选方案)。
第四步,权衡利弊。结合上面的内容进行脑暴讨论,最终进行利弊评估。评测当前技术债是否需要进行技改。
制定偿还计划
首先,需要对现有系统进行全面的评估,确定存在哪些技术债,并对其严重程度进行评估。其次,根据技术债的严重程度和业务需求,确定偿还的优先级。优先处理那些对系统性能、稳定性和安全性影响较大的技术债。
每一项变更都是需要编写一份详细的设计文档,这里就不详细概率。可以阅读之前的文章来了解如何编写一份全面的 设计文档
为了保证偿还计划的顺利进行,需要为其分配足够的资源,包括人力、时间和资金等。并且定期对偿还计划进行评估,检查计划的执行情况,及时调整计划。
如何安全地在现有代码库中修改代码
- 定义变更点。归纳出需要变更的地方有哪些,并总结在设计文档中进行记录。
- 寻找测试点。以变更的地方为中心,寻找进行验证变更的方式。
- 打破依赖关系。过手的代码必须干净,每次过手的代码不要产生更多的技术债。降低功能中高耦合的成分。
- 编写测试。为你本次的修复变更编写测试代码。最大限度的覆盖你所有的变更范围,尤其是极端操作和临界值。
代码从不说谎,注释有时却会
进行债务修复的时候,需要认真审视被变更的地方。不能只通过相关文档或者注释的内容就开始进行变更。变更前,一定要去整理被变更的整条链路的逻辑后在进行变更。文档和注释往往不是百分百可以信任的。
做渐变式的修改
一般重构会采用下面两种方式中的一种。
- 巨大的"翻天覆地"式的代码变更,一次性修改几十个文件。
- 在一个混乱的拉动请求中即有重构也有新特性。
这两种方式的修改都很难进行代码评审。这种合并方式使得只想恢复特性而不影响那些用以重构的代码的回滚操作变得非常困难。
应该保持你每次重构代码的体积量很小。为代码变更算法中的每个步骤提交单独的拉动请求。
归纳
技术债是软件开发中不可避免的问题,但是你不必为此使自己感到心情低落。 我们需要重视技术债的管理,制定合理的偿还计划,逐步处理技术债,提高代码质量和开发效率。
感谢(题外话)🌸
本节内容参考了 《程序的README》 -- 3.2 技术债。