大家好,我是阿萨。 今天聊一个软件团队都会碰到的问题。 技术债务产生的原因。
什么是技术债?
技术债务反映了一个痛苦的现实——在快速软件交付的短期利益和长期价值之间进行权衡。当开发人员编写一个新的软件功能时,有两个选择:简单的路线,为了让一些需求工作而编写糟糕、混乱的代码。更难的路线是花费大量时间于设计、架构和适当的编码实践,并产生高质量的程序。这两条路线之间的差距是技术债务。
技术债务不是我们的错
技术债务积累的原因是多方面的。他们的共同之处在于,无论你问谁,他们都会告诉你:这不是我们的错。让我们来看看五个常见的原因,看看谁才是真正的罪魁祸首,以及你能做些什么。
- 瀑布的传承
遗留系统是技术债务的典型来源。如果正在开发一个已有15年历史的系统,其中包含数百万行代码,使用瀑布式实践构建,那么很明显团队一定正在经历技术债务的困扰。
- 不愿意碰老代码
考虑遗留系统的典型方式是“如果它没有坏,就不要修复它”。开发人员害怕接触遗留代码,并在不经意间添加越来越多与原始代码非常相似的遗留代码。
- 不愿意承担责任
将遗留系统视为不应该触及的圣牛,会导致我们保留最初的罪魁祸首,并继续积累技术债务。
问问自己——即使有大量的技术债务,我们的方向是什么?一周后,一个月后,或一年之后,我们的技术债务会减少还是增加?如果你的方向是积极的,你就会逐渐消除技术债务,改善你的情况,你就会承担起问题的责任,最终,它会消失。
- 缺失的文件
技术债务的一种常见形式是缺少文档。我们建立了一个功能,它可以工作,但没有人知道它是如何工作的。或者它是以这样一种方式记录的,只有从事该功能的开发人员才能真正理解它。
- 前人的锅我不背
几乎所有的开发人员都继承了以前的文档,而且很少有人对自己的继承感到满意。如果文档是由之前在这个项目中工作的团队或其他在邻近项目中工作的团队编写的,那就更不是我们的错,对吗?
我们能做什么来缓解技术债务
在软件项目的生命周期中,大多数(如果不是全部的话)特性都会被修改、改动、改进、替换或增强。如果接触到一个特性,即使没有实质性地修改它,也要在那时重新查看文档。现在已经熟悉了该特性,看过代码,了解了它的功能。现在就花点时间来写正确的文档——否则就没人会写了。
逐步通过文档和添加与我们当前项目工作相关的零碎内容,最终将缓解问题。而且它不需要大型文档重写的投入。只需要几分钟或几个小时(取决于范围)就可以搞定。
用好完成的定义 DoD
技术债务的一个主要原因是团队中商定的完成定义(DoD)。完成的定义让我们进退两难:
如果我们在“完成”的定义中加入许多强制性的项目,使其成为一个无穷尽的清单,人们将不可避免地忽略清单中的部分内容来完成任务。
如果我们将项目定义为“优先发布”,那么它们往往会被冲刺压力推到一边。
如果我们只保留一个最小的关键项目列表——例如,单元测试和验收测试——从长远来看,其他更重要的考虑因素,如设计和架构,可能会被忽略。
- 一定要有DoD
我们没有完成的定义。或者至少,我们不是单个人完成的。这是整个团队的责任。如果DoD不实现,我们怎么能在不增加技术债务的情况下完成冲刺呢?
- 灵活运用DoD
每个团队成员都可以做出认真的决定,这些决定会影响sprint中的工作并减少技术债务。没有DoD是完美的。但是在冲刺阶段,开发人员可以做出明智的决定——他们可以确定DoD中的哪些项目可以完全忽略,即使它们是强制性的。或者哪些项目现在必须完成,即使它们只是建议,或者根本没有出现在DoD。
- 避免承担超出能力范围的工作
在“冲刺”中工作的敏捷团队经常发现自己吃了超过他们能承受的东西。要么故事被低估了,要么管理层增加了交付的压力,团队最终承诺的工作超过了sprint期间实际可以完成的工作。
因为交付是“可预测的”,而sprint通常是交付给最终用户的,所以通常除了完成sprint范围之外别无选择——即使是为了达到目标而抄近路。从长远来看,这种非常常见的行为会导致巨大的技术债务。
- 承担超出范围的内容 的根因
承担超出我们承受能力的工作量通常不是一个有意识或自愿的决定。它是由来自高层要求“提高速度”的压力,由发布周期中逐渐发生的范围变化,或由低估或误解开发特定功能所需要的东西引起的。
- 有勇气说不
如果你需要有人来修理你的房子,一个好的水管工或电工是一个可以说不的人——如果他们不能按时完成工作,或者不能做好,他们就不会接受。如果他们接受了,他们将承担全部责任,按时做好工作。
这与开发团队是一样的——即使软件工程的复杂性和不可预测性,负责任的团队也有勇气对不合理的管理要求说“不”,并仔细进行sprint计划以调查和验证故事估计。如果处理得当,就会知道偶尔会出现意料之外的超量,并能够集中精力解决它,理解这是例外而不是规则。
- 技术债务会导致软件质量差
一种潜在的技术债务形式是软件可以工作,但充满了漏洞。其中一些可能会在发布后不久在生产中被发现,而另一些可能会潜伏几个月甚至几年,直到出现灾难性的生产故障。
- 测不全会导致技术债务被掩盖
随着软件系统日益复杂,不可能测试所有东西。无论关注的是全面的单元测试覆盖、主要组件之间的集成测试、UI测试自动化,还是某些组合,都一定会错过系统的某些部分或某些对功能、稳定性或性能至关重要的连接。
- 做好质量
质量是一个棘手的问题,因为编写测试需要时间,而我们在有限的冲刺范围内没有时间。如何利用宝贵的时间来确定能够防止生产问题并让客户满意的正确测试?这是每个人都必须思考的问题。
看完前面的原因分析,我们了解了技术债务产生的根因之后,相信大家一定会找到减少技术债务的方法。