尽管实践中会堆积技术债,但这个概念并不在我们的工作中频繁出现。这篇文章就系统性讲讲技术债,让大家避免知其然,不知其所以然。
一、技术债是什么
技术负债(英语:Technical debt),又译技术债,也称为设计负债(design debt)、代码负债(code debt),是编程及软件工程中的借鉴了财务债务的系统隐喻。指开发人员为了加速软件开发,在应该采用最佳方案时进行了妥协,改用了短期内能加速软件开发的方案,从而在未来给自己带来的额外开发负担。这种技术上的选择,就像一笔债务一样,虽然眼前看起来可以得到好处,但必须在未来偿还。软件工程师必须付出额外的时间和精力持续修复之前的妥协所造成的问题及副作用,或是进行重构,把架构改善为最佳实现方式。
1992年,沃德·坎宁安首次将技术的复杂比作为负债。第一次发布代码,就好比借了一笔钱。只要通过不断重写来偿还债务,小额负债便可以加速开发。但久未偿还债务会引发危险。复用马马虎虎的代码,类似于负债的利息。整个部门有可能因为松散的实现,不完全的面向对象的设计或其他诸如此类的负债而陷入窘境。
二、技术债表现
技术债与其他债务本身一样,是一种透支行为,通过牺牲未来来满足当下的一些需求。也跟其他债务一样,技术债务也有利息,而且随着时间利滚利,会成为埋在项目里的定时炸弹。如果产品长期的可持续的发展,那么技术债的重要性是毋庸置疑的。
技术债务的本质是产品的结构阻碍了进步,表现出来的症状有:无法轻易重构产品以满足市场需求;组件之间的依赖性过多,体系结构不良;缺陷太多,结构不良;难以理解,难以改变。
技术债务的后果有偿还技术债务造成时间浪费,员工满意度降低带来士气低落,因解决遗留代码问题而错过优质项目造成人才流失,产品质量降低造成客户满意度下降,技术债务限制创新能力、扼杀创造性等诸多问题。
技术债不单单是技术债,它就像一个垃圾堆,久而久之不处理,慢慢周围就会产生更多的垃圾,因此产生的“破窗效应”更加是会对未来的项目环境造成很大的影响,大家也会逐渐丧失维护环境的信心。所以在讨论技术债的时候不仅仅是讨论技术债本身,技术债对团队追求质量的信心、对大家维护环境整洁的积极性都会造成很大的影响。
Martin Fowler把技术债分为四个象限,如下图所示:
三、技术债产生的原因
业务压力:为了满足业务的快速要求,在必要的修改并没有完成时就匆匆发布,这些未完成的修改就形成了技术负债。
缺少过程和理解:业务人员不清楚不理解技术负债的概念,在决策时就不会考虑到其带来的影响。
模块之间解耦不够:功能没有模块化,软件柔性不够,不足适应业务变化的要求。
缺少配套的自动化测试:导致鼓励快速而风险很大的“创可贴”式的BUG修复。
缺少必要文档:需求和代码都没有必要的支撑性文档或注释。
缺少协作:组织中的知识共享和业务效率较低,或者初级开发者缺少必要的指导。
重构延迟:在开发的过程中,某些部分的代码会变得难以控制,这时候就需要进行重构,以适应将来的需求变化。重构越是推迟,这些已有的代码被使用的越多,形成的技术负债就越多,直到重构完成。
不遵循标准或最佳实践:忽略了已有的业界标准、框架、技术和最佳实践。
缺少相关技能:开发人员有时候技能缺失,并不知道如何编写优雅的代码。
四、如何“还债”?
1.技术债可视化
尽可能公开技术债,一开始就与团队,利益相关方一起权衡利弊,并明确告知影响与解决方案。平等沟通,相互理解。让技术债在业务层面、技术层面可见。
可以在组织资产负债表的财产债中新增两列:短期技术债和长期技术债。还可以用用跟踪开发速率的方式体现技术债对于产品的影响。
2.不同的债要对症下药
技术债的状态可以分类为偶然技术债、已知技术债和目标技术债。
偿还技术债时应遵循如下原则:
1)确定已知技术债必须还。
2)发现偶然技术债,立即还。
3)每个冲刺确定一定数量的已知技术债作为目标技术债,在当前冲刺中偿还。
4)无需偿还的技术债是行将就木的产品、一次性原型和短命产品。
五、如何避免“欠债”
与其后期吭哧吭哧还债填坑,不如从一开始就尽量避免欠下技术债务。
1.避免使用过时的技术
遗留应用程序、过时的技术以及不同的平台和流程可能会使组织陷入沉重的技术债务,迫使其推迟基本的现代化计划。DNS和流量管理技术提供商NS1的联合创始人兼首席执行官Kris Beevers说:“技术债务将大量金钱和宝贵的时间浪费在系统和应用程序上,而这些系统和应用程序并不是为现代企业所需的规模和速度而打造的。”
旧资产和老方法也往往充斥着安全漏洞,难以集成和自动化,并且很可能不再更新。 Beevers指出:“寻找人才来管理基于复杂或过时的代码构建的遗留应用程序也是一个日益严峻的难题。坚持采用过时技术不仅会消耗宝贵的预算,而且还会阻碍公司创新和保持竞争力的能力。”
2.参考敏捷实践
有越来越多的组织渐渐接受敏捷软件开发,这是将方法交给协作、自行组织的团队和跨职能团队的一系列方法和实践。如果这种方法得到严格应用,敏捷开发使组织可以避免技术债务,其方法是快速且以迭代的方式创建和发布新产品。Dodd说:“这一过程将新产品和新功能尽快并逐步地交到用户手中。”随着新版本的交付,各种改进和问题都得到了解决,这使技术债务的积累不太可能产生。
敏捷方法认识到项目在生命周期中从未真正完成过,并且也从来都不是完美的。“同时,敏捷方法专注于……针对能力和质量的简化了的开发”,Dodd说。重要功能往往要频繁地开发,测试并投入生产。敏捷团队可能不会发布软件的“全面(Big Bang)”方法,而是每年发布几次重大升级。Dodd指出:“这可以使产品保持相当平稳的发展,还可以帮助用户避免重大的中断事件。”
3.遵循代码规范
是否遵守了编码规范,是否遵循最佳实践也是影响技术债的一个方面。代码规范在研发项目团队中有着重要作用,团队统一代码规范,有助于提升代码可读性以及工作效率。统一的
代码规范是代码集体所有权的基础,会让结对编程更容易实行,对团队来说更易内部轮岗、获得晋升。代码规范和代码质量工具有助于发现代码质量方面的技术债务。
亡羊补牢,为时未晚。从现在开始把偿还技术债务纳入backlog,把避免产生技债务作为工作准则,相信不会出现被技术债务压垮崩溃的情况。