技术债务是指开发人员为了加速软件开发,在应该采用最佳方案时进行了妥协,改用了短期内能加速软件开发的方案,以至于未来给自己带来额外的开发负担。

软件工程师 Ward Cunningham首次将技术的复杂比作为负债。 简单来说,技术债务类似于金融债务,软件开发就像是去银行 “贷款”,而技术债务就像是贷款的“利息”。“利息”是需要以未来额外的时间来偿还的,所以重构才相当于支付“本金”。

表面上,软件的应用程序看起来质量很高且状况很好,但是这些问题却隐藏在下面。如果没有很好地管理并设法降低这些技术债务,那么程序编写和维护的代价最终将会超过它对客户的价值。

这些技术债务到底是从何而来?为什么某些团队在 Scrum开发过程中会导致技术债务的积累呢?我们该如何解决技术债务呢?

一、 Scrum环境产生技术债务的原因

为了满足 Sprint冲刺目标、发布功能和不断变化的需求,开发人员可能会更加关注短期收益,而忽视长期代码质量和可维护性。 因此,开发人员会在必要的修改没有完成时就匆匆发布,权宜之计在不知不觉中就产生技术债务。

技术债务会导致 Scrum团队产生生产力下降、代码质量下降、项目风险增加等多种影响。 虽然在下一个迭代中偿还技术债务是可行的,但团队需要关注每个迭代的新需求,不可能永远都在救火。

那么我们该如何偿还技术债务?或者该如何避免产生技术债务呢?

二、技术债务如何还债

在 Scrum环境中,偿还技术债务是一个重要的任务,以确保软件的可持续发展和质量。下面是一些偿还技术债务的方法:

  • 识别技术债务

首先,团队需要识别和记录技术债务。这可以通过代码审查、静态代码分析、系统性能监测等方式来发现潜在的问题和改进点。技术债务可以包括代码质量问题、未完成的任务、过时的技术选择等。

  • 优先级排序

一旦技术债务被识别,团队需要对其进行优先级排序。这可以基于影响业务价值、风险和复杂性等因素来确定。团队可以与利益相关者协商,以确保优先处理对业务和用户最重要的技术债务。

  • 制定计划

根据优先级排序,团队可以制定一个技术债务偿还计划。这个计划应该包括具体的任务、时间估计和分配给团队成员的工作量。团队可以将这些任务添加到产品待办列表中,并在每个迭代中分配一定的时间来处理技术债务。

  • 项目结构化

减少技术债务的有效方式之一是通过更好地构建项目来最大程度地减少技术债务。使用项目管理工具(如禅道)可以帮助团队跟踪开发状态,保持进度,并提高团队的整体协作效率。

  • 自动化测试

在偿还技术债务的过程中,团队可以优先考虑编写自动化测试来确保代码的正确性和稳定性。自动化测试可以帮助团队及时发现和解决问题,并减少未来的技术债务积累。

禅道团队自研了开源的自动化测试框架 ZTF和通用数据生成器ZenData,加上禅道项目管理软件构成了专业的自动化测试解决方案,可以帮助用户实现规模化自动化测试,提升测试效率。

  • 分配固定重构时间

重构相当于贷款需要偿还支付 “本金”,所以 每个 Sprint中分配固定的时间进行重构。这可以是若干小时数、若干故事点数,如一个团队可以为重构预留30个小时、4个故事点等。在Scrum环境中,持续改进是一个核心原则,只有定期回顾和评估偿还技术债务的进展,才能够一定程度上避免技术债务带来的消极影响。

通过遵循这些策略, Scrum团队可以有效地管理和减少技术债务,从而产生更高质量的软件产品并提高团队生产力。

三、写在最后

正如电影《无间道》所说 “出来混,迟早要还的”,技术债是无法避免的,只是产生技术债务多少的问题,但如果不及时处理技术债务就会产生破窗效应。 团队欠下太多技术债务,必然导致影响后期的代码质量下降,这也会间接影响到完全没有关联的其他用户故事的研发。

因此,从现在开始把偿还技术债务纳入待办事项中,把避免产生技术债务作为工作准则!

我们不可能永远都在救火 ——Scrum中技术债务“偿还”指南的更多相关文章

  1. JavaScript中的闭包永远都存储在内存中,除非关闭浏览器

    //閉包實現累加功能 function fn1() { var n = 1; add = function() { n += 1; } function fn2() { n += 1; console ...

  2. fileUpload1.HasFile的返回值永远都是false的问题处理

    在aspnet项目中,如果有页面使用了fileupload,不巧你也在此页面使用了updatepanel局部刷新控件,那马就会出现一个很奇怪的问题:就是不管你选择文件了没有,fileUpload1.H ...

  3. element-UI el-table添加序号列时序号永远都是从1开始?

    Part.1 示例 当我们想在 el-table 中添加序号列时,如下: <el-table-column label="序号" type="index" ...

  4. 【译】为什么永远都不要使用MongoDB Why You Should Never Use MongoDB

    背景 最近在学习DDIA(Designing Data-Intensive Applications)这本分布式领域非常急经典的入门书籍,里面第二章<数据模型与查询语言>,强调了对一对多. ...

  5. 如何处理scrum中未完成的用户故事?

    你听过柏林新建机场的故事吗?机场原定2006年开工,2007年启用,但由于机场建设过程中到处出现施工和安全问题,补东墙漏西墙,导致工期一拖再拖,预算一涨再涨,以至于2019年了还没开张,预计开业时间已 ...

  6. 【转】为什么我们都理解错了HTTP中GET与POST的区别

    GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数. 你可能自己 ...

  7. 为什么模板函数的声明和实现都放在.h文件中

    当你不使用这个模板函数或模板类,编译器并不实例化它,当你使用时,编译器需要实例化它,因为编译器是一次只能处理一个编译单元,也就是一次处理一个cpp文件,所以实例化时需要看到该模板的完整定义.所以都放在 ...

  8. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  9. 发生dev_queue_xmit的时候,全部都是从ip_finish_output中来的吗

    也就是说啊,内核中的收发包的路径,很可能是经理driver_recv --> tcp -->driver_send这样一个过程,是个很长的路径呢...... 从dev_queue_xmit ...

  10. 我们知道写入过程比ZooKeeper集合中的读取过程要贵,因为所有节点都需要在数据库中写入相同的数据。因此,对于平衡的环境拥有较少数量(例如3,5,7)的节点比拥有大量的节点要好。

    我们知道写入过程比ZooKeeper集合中的读取过程要贵,因为所有节点都需要在数据库中写入相同的数据.因此,对于平衡的环境拥有较少数量(例如3,5,7)的节点比拥有大量的节点要好. 组件 描述 写入( ...

随机推荐

  1. 【BUG】axios 长数字精度丢失问题

    问题原因 出现改问题是于javascript 整数范围问题 java 中 Long 类型 -2的63次方 - 2的63次方减去1 但是javascript整数范围确没有那么大,导致Long数字过大前端 ...

  2. Git提交历史优化指南:两步合并本地Commit,代码审查更高效!

    在开发过程中,频繁的本地Commit可能导致提交历史冗杂,增加代码审查和维护的复杂度.通过合并连续的Commit,不仅能简化历史记录,还能提升代码可读性和团队协作效率,以下是合并两次本地Commit的 ...

  3. php文件和文件夹操作类

    文件和文件夹操作 移动 | 复制 | 删除 | 重命名 | 下载 <?php namespace Framework\Tools; use PharData; class FileManager ...

  4. SLAM在机器人中的应用

    SLAM在机器人中的应用​ 伴随着人工智能.机器人.无人驾驶等技术的蓬勃发展,越来越多的相关智能产品出现在了我们的日常生活中,作为底层技术基石之一的SLAM也逐渐被大家所熟知.下面通过"机器 ...

  5. 浅谈Ubuntu中的软件包

    1. 前言 还记得大学第一次接触Ubuntu和Linux的时候,觉得用apt安装想要的软件非常方便.但是有时候出现了问题,各种报错,自己又不懂原理,就会非常抓狂.现在稍微理解一点了,故以较为容易理解的 ...

  6. C# 调用 Win10/11 文件关联对话框

    方法一:调用未公开接口 IOpenWithLauncher Adobe Acrobat 应该是调用的未公开接口方法 [ComImport] [InterfaceType(ComInterfaceTyp ...

  7. C# 多项目打包时如何将项目引用转为包依赖

    项目背景 最近开发一组类库,大约会有五六个项目.一个Core,加上若干面向不同产品的实现库,A/B/C/D...它们都依赖Core. 首先,我想统一版本号,这个容易,通过Directory.Build ...

  8. mybatis插入数据返回id的实现方式

    一. useGeneratedKeys="true" <insert id="saveUser" parameterType="com.apcs ...

  9. 基于Redission实现分布式调度任务选主

    在Spring Cloud微服务架构中,基于Redisson实现分布式调度任务的选主和心跳监听,可以通过以下完整方案实现.该方案结合了Redisson的分布式锁和发布/订阅功能,确保高可靠性和实时性: ...

  10. app自动化的特殊操作

    一.截屏 File srcfile=driver.getScreenshotAs(OutputType.FILE); //得到截图源文件对象 File dstfile=new File("C ...