技术债是我们的错吗?

简介: 技术债是我们的错吗?

大家好,我是阿萨。 今天聊一个软件团队都会碰到的问题。 技术债务产生的原因。


什么是技术债?


技术债务反映了一个痛苦的现实——在快速软件交付的短期利益和长期价值之间进行权衡。当开发人员编写一个新的软件功能时,有两个选择:简单的路线,为了让一些需求工作而编写糟糕、混乱的代码。更难的路线是花费大量时间于设计、架构和适当的编码实践,并产生高质量的程序。这两条路线之间的差距是技术债务。

 

技术债务不是我们的错


技术债务积累的原因是多方面的。他们的共同之处在于,无论你问谁,他们都会告诉你:这不是我们的错。让我们来看看五个常见的原因,看看谁才是真正的罪魁祸首,以及你能做些什么。

 

  • 瀑布的传承


遗留系统是技术债务的典型来源。如果正在开发一个已有15年历史的系统,其中包含数百万行代码,使用瀑布式实践构建,那么很明显团队一定正在经历技术债务的困扰。

 

  • 不愿意碰老代码

 

考虑遗留系统的典型方式是“如果它没有坏,就不要修复它”。开发人员害怕接触遗留代码,并在不经意间添加越来越多与原始代码非常相似的遗留代码。

 

  • 不愿意承担责任

 

将遗留系统视为不应该触及的圣牛,会导致我们保留最初的罪魁祸首,并继续积累技术债务。

 

问问自己——即使有大量的技术债务,我们的方向是什么?一周后,一个月后,或一年之后,我们的技术债务会减少还是增加?如果你的方向是积极的,你就会逐渐消除技术债务,改善你的情况,你就会承担起问题的责任,最终,它会消失。

 

  • 缺失的文件


技术债务的一种常见形式是缺少文档。我们建立了一个功能,它可以工作,但没有人知道它是如何工作的。或者它是以这样一种方式记录的,只有从事该功能的开发人员才能真正理解它。

 

  • 前人的锅我不背

 

几乎所有的开发人员都继承了以前的文档,而且很少有人对自己的继承感到满意。如果文档是由之前在这个项目中工作的团队或其他在邻近项目中工作的团队编写的,那就更不是我们的错,对吗?

 

我们能做什么来缓解技术债务

 

在软件项目的生命周期中,大多数(如果不是全部的话)特性都会被修改、改动、改进、替换或增强。如果接触到一个特性,即使没有实质性地修改它,也要在那时重新查看文档。现在已经熟悉了该特性,看过代码,了解了它的功能。现在就花点时间来写正确的文档——否则就没人会写了。

 

逐步通过文档和添加与我们当前项目工作相关的零碎内容,最终将缓解问题。而且它不需要大型文档重写的投入。只需要几分钟或几个小时(取决于范围)就可以搞定。

 

用好完成的定义 DoD


技术债务的一个主要原因是团队中商定的完成定义(DoD)。完成的定义让我们进退两难:

 

如果我们在“完成”的定义中加入许多强制性的项目,使其成为一个无穷尽的清单,人们将不可避免地忽略清单中的部分内容来完成任务。


如果我们将项目定义为“优先发布”,那么它们往往会被冲刺压力推到一边。


如果我们只保留一个最小的关键项目列表——例如,单元测试和验收测试——从长远来看,其他更重要的考虑因素,如设计和架构,可能会被忽略。


  • 一定要有DoD 

我们没有完成的定义。或者至少,我们不是单个人完成的。这是整个团队的责任。如果DoD不实现,我们怎么能在不增加技术债务的情况下完成冲刺呢?

 

  • 灵活运用DoD

 

每个团队成员都可以做出认真的决定,这些决定会影响sprint中的工作并减少技术债务。没有DoD是完美的。但是在冲刺阶段,开发人员可以做出明智的决定——他们可以确定DoD中的哪些项目可以完全忽略,即使它们是强制性的。或者哪些项目现在必须完成,即使它们只是建议,或者根本没有出现在DoD。

 

  • 避免承担超出能力范围的工作

在“冲刺”中工作的敏捷团队经常发现自己吃了超过他们能承受的东西。要么故事被低估了,要么管理层增加了交付的压力,团队最终承诺的工作超过了sprint期间实际可以完成的工作。

 

因为交付是“可预测的”,而sprint通常是交付给最终用户的,所以通常除了完成sprint范围之外别无选择——即使是为了达到目标而抄近路。从长远来看,这种非常常见的行为会导致巨大的技术债务。

 

  • 承担超出范围的内容 的根因

 

承担超出我们承受能力的工作量通常不是一个有意识或自愿的决定。它是由来自高层要求“提高速度”的压力,由发布周期中逐渐发生的范围变化,或由低估或误解开发特定功能所需要的东西引起的。

 

  • 有勇气说不

 

如果你需要有人来修理你的房子,一个好的水管工或电工是一个可以说不的人——如果他们不能按时完成工作,或者不能做好,他们就不会接受。如果他们接受了,他们将承担全部责任,按时做好工作。

 

这与开发团队是一样的——即使软件工程的复杂性和不可预测性,负责任的团队也有勇气对不合理的管理要求说“不”,并仔细进行sprint计划以调查和验证故事估计。如果处理得当,就会知道偶尔会出现意料之外的超量,并能够集中精力解决它,理解这是例外而不是规则。

 

  • 技术债务会导致软件质量差

一种潜在的技术债务形式是软件可以工作,但充满了漏洞。其中一些可能会在发布后不久在生产中被发现,而另一些可能会潜伏几个月甚至几年,直到出现灾难性的生产故障。

 

  • 测不全会导致技术债务被掩盖

 

随着软件系统日益复杂,不可能测试所有东西。无论关注的是全面的单元测试覆盖、主要组件之间的集成测试、UI测试自动化,还是某些组合,都一定会错过系统的某些部分或某些对功能、稳定性或性能至关重要的连接。

 

  • 做好质量

 

质量是一个棘手的问题,因为编写测试需要时间,而我们在有限的冲刺范围内没有时间。如何利用宝贵的时间来确定能够防止生产问题并让客户满意的正确测试?这是每个人都必须思考的问题。


看完前面的原因分析,我们了解了技术债务产生的根因之后,相信大家一定会找到减少技术债务的方法。


相关文章
|
6月前
|
测试技术
解决Bug应有的心态和解决方法的一些思路、方法和心得
永远要相信程序是不会骗你的,是自己在处理理逻辑中出问题,而在特定的环境中才会出现或者是自己压根就想不到情况下出现。 前几天在处理一个接口任务时,在测试环境跑是一点都没有,但在正式环境却没有将数据拉下来。没有报任何错误,一度怀疑、抱怨! 还好最后找到问题解决了!
33 0
|
Java API C#
这样在 C# 使用 LongRunnigTask 是错的
Task.Factory.StartNew 有一个重载,是支持 TaskCreationOptions.LongRunning 参数来指定 Task 的特征的。但是可能在没有注意的情况下,你就使用了错误的用法。那么本文我们来简单阐述一下这个参数的作用,和使用的注意要点。
106 0
这样在 C# 使用 LongRunnigTask 是错的
|
程序员
编程基本功:找到问题的合理解释,才算解决问题
编程基本功:找到问题的合理解释,才算解决问题
64 0
|
安全 编译器 C++
还在纠结VS用scanf会被报错,一招设置轻松解决问题
vs2019使用scanf会产生的问题的解决方案之一
264 0
还在纠结VS用scanf会被报错,一招设置轻松解决问题
|
Python
4.10错的的题
4.10错的的题
256 0
|
Linux
出现问题,不经过吾确认,都不能作为结论
出现问题,不经过吾确认,都不能作为结论
54 0
|
设计模式 Java 编译器
恕我直言,我怀疑你没怎么用过枚举
我们是否一样? 估计很多小伙伴(也包括我自己)都有这种情况,在自学Java语言看书时,关于枚举enum这一块的知识点可能都有点 “轻敌” ,觉得这块内容非常简单,一带而过,而且在实际写代码过程中也不注意运用。 是的,我也是这样!直到有一天我提的代码审核没过,被技术总监一顿批,我才重新拿起了《Java编程思想》,把枚举这块的知识点重新又审视了一遍。 为什么需要枚举 常量定义它不香吗?为啥非得用枚举? 举个栗子,就以B站上传视频为例,视频一般有三个状态:草稿、审核和发布,我们可以将其定义为静态常量: public class VideoStatus { public st
116 0
|
架构师 Java 容器
我在系统设计上犯过的14个错
除了自己犯的错以外,也还看过其他同学犯的一些错,这个在后面再写一篇文章来分享下,同时也征集大家印象深刻的推倒重来的系统设计的错
907 0
|
程序员