InfoQ Geekathon 大模型技术应用创新大赛 了解详情
写点什么

务实的技术债务管理

  • 2015-10-21
  • 本文字数:4198 字

    阅读完需:约 14 分钟

技术债务概述

技术债务是由 Ward Cunningham 在 1992 年的报告 [1] 创造的一个比喻,被定义为当我们有意或无意地做了错误的或不理想的技术决策 [2] 所累积的债务。它和金融债务非常相似。一个人贷款了就会产生债务。如果他定期还款,那么所创建的债务是可以接受的,不会产生进一步的问题。但是,如果他不还款,就会以利息作为惩罚,并随着不还款次数的增加而增加。如果这个人很长一段时间不能支付任何款项,那么应计利息使得他更难以偿还债务。在极端情况下,该人不得不宣布自己破产。

同样地,当一个人采用一个非最优或次优技术决定,他就引入了技术债务。如果不及时纠正,该决定将影响其它相关技术的决定,债务开始上升。在很长一段时间未偿还累计的技术债务的情况下,软件越来越难以改变,在极端情况下,软件产品变得在技术上已经破产(即在规定的时间引入一个可靠地变化是不可行的)。这种情况往往会导致项目终止。

为什么软件从业者意识到技术债务很重要?为什么一定要避免引入它?要理解这一点,让我们先了解技术债务的组成部分。技术债务本就是本金(最原始的 hack 或者捷径),而当本金不能按时偿还时,就会累积利息。 利息有复合的性质:开发团队越是忽略或推迟它,随着时间的推移,债务变得越大。因此,是利息使得技术债务成为一个显著问题。

巨大的技术债务影响了软件开发团队的生产效率,并降低他们的士气和积极性。技术债务不断累积导致了恶性循环:巨大的技术债务降低了生产效率和团队的士气 ; 同时低生产效率使得管理者推出更多的功能并导致技术债务问题的延期,而这又进一步增加了技术债务。

技术债务是多方面的。一些突出的方面是:

  • 产生债务:例如 - 代码重复、违反静态工具规则和代码异味。
  • 设计和架构债务:例如 - 设计异味、违反设计规则和违反架构规则。
  • 测试债务:例如 - 缺乏测试、测试覆盖面不足和不正确的测试设计。
  • 文档债务:例如 - 没有重大问题的文档、缺乏文档和文档过期。

图 1:技术债务的维度

一个技术债务的类型是由它产生的原因和方式来定义的。一种著名的技术债务分类如下:

  • 战略债务:- 这种类型的债务是在知情的状况下为了战略利益(例如首次市场发行)而产生,并长期存在。
  • 战术债务:- 这种类型的债务是在知情的情况下为了快速收益而产生,通常适用于短期。
  • 疏忽债务:- 不慎产生的债务通常是在不知情的情况由于缺乏知识和意识而产生。
  • 增量债务:- 定期不慎产生的债务导致增量债务。

管理技术债务

“债务是必然的!”在这个快节奏的世界,软件开发团队有责任迅速提供价值给客户。在这种追求中,有各种情况团队必须选择快速和肮脏的解决方案。在这种情况下,采取勤奋和务实的态度处理技术债务问题是很重要的。

第一个方面的管理技术债务是“防止”技术债务积聚。它包括增加有关技术债务的软件开发团队的认识并在组织内引入相关流程。另一个方面管理技术债务是为了“偿还”技术债务。需要有意识的努力以鉴别、优先处理和重构在实际项目的技术债务问题。让我们在下面更详细地讨论这些方面。

防止技术债务产生

防止技术债务产生的主要方法是,使人们了解开发团队存在的技术债务。开发团队必须了解技术债务,它的各种方面和类型,以及债务对他们的项目的影响。他们必须具备完善的设施与代码质量的概念,干净的编码习惯、设计嗅觉、以及如何重构它们。

理解和认识有关最佳实践和上述概念的程度可以通过开展集中培训,以及举办研讨会和会议得到提升。

用人相关的流程可以帮助开发团队避免技术债务积累。这样的方法的典型例子是审查过程(如代码、设计、架构和测试审查)和架构管理(例如:以确保该代码符合预期的体系结构和设计)。然而,所采用的流程必须是务实的:顽固和艰难地遵循流程会阻止团队从完全遵循它们,并在坚持的过程带领他们寻求捷径。

偿还技术债务

通常情况下,团队在已经积累了大量的技术债务的项目中工作。在这种情况下,忽视债务前进是不明智的,因为它可能会导致该项目技术破产。在另一方面,停止数个月不开发新功能转而只专注于偿还技术债务也是不可行和不实用的。

在这些情况下,需要均衡的发展模式,稳步偿还债务,并尽可能地保持功能和软件的实用性的进度。现在让我们讨论一些偿还技术债务的务实策略。

1. 识别、记录和追踪债务

偿还技术债务的第一步是识别并记录现有债务。有许多工具可以用来识别各种技术债务 [4] 的具体实例。此外,团队的经验丰富的开发人员和架构师也可以识别的债务情况。一旦确定,债务情况必须以一个合适的形式记录下来。可以用简单的 Excel 工作表或使用如 Teamscale [5] 一样强大的工具。然后,记录的债务情况需要加以评估而且他们的状态必须被跟踪(团队是否会解决这些问题,如果是,谁将会解决这些问题,何时解决)。

2. 优先处理异味

并非所有的债务都是一样的 - 不同类型的债务都设有不同的利率。因此,所识别的债务实例必须优先考虑用于基于以下因素重构,如债务实例对项目的潜在影响。在现实世界中的项目 100% 偿还债务是不切实际的(事实上也不推荐); 存在一些(低优先级)债务以保持功能开发和技术偿还债务之间的平衡是可以的。

3. 在每个迭代中分期偿还债务

在金融领域,如果一个人有一个大的贷款(比如住房贷款),一次性偿还所有债务是不可能的 ; 但是,通过支付 EMIs 贷款(等同于每月分期付款)来偿还债务绝度是更容易的。同样地,项目团队一次性偿还巨额的技术债务是不可能的 ; 然而,以小额分期付款的形式还款 - REIs(等同于分期付款)是非常可行和实用的,即努力在每次迭代中为重构留出一小部分精力。

4,激励和奖励员工保持品质

“人们关心的是你衡量和奖励的事情。”如果一个软件开发团队的经理以团队交付功能的数量或修复缺陷的数量为准绳衡量团队的表现,那么团队将只专注于增加功能和修复缺陷。做好它和完成它同样重要。保持高度的积极性,不仅为了开发工作的代码同时为了代码质量而奖励队员,这是对抗高技术债务和恶化质量的关键策略。

5. 遵循“男孩的童子军规则”

男孩的童子军规则例如,“要始终保持营地比你发现它的时候更清洁”也是适用于软件开发的:“提交的代码比检出的要更好”。鼓励团队成员,以积极减少技术债务 ; 例如,当他们发现了一块为了功能增加或错误修复的代码时激励他们重构。

6. 留意可能出现的大规模的债务偿还

大范围的债务偿还类似于在收到来自雇主的奖金时支付大的家庭贷款的一部分。比如说,在一次重大的发行之后,继续大范围寻找机会偿还债务。大规模的变化,如进行架构重构,可以有助于大幅减少技术债务。另一方面,在进行这样大规模的债务偿还时需要大量的规划和有效的沟通,以减少相关的风险。

7. 平地偿还债务而不是垂直地

属于不同维度的债务实例相互影响。例如,属于测试和设计债务的实例可能是相关的。为了使代码可测试(或反之亦然),改变一些设计决策是有可能的。因此,而不是试图完全偿还技术债务的一个层面,试图偿还与一个实体(一个类、文件或组件)有联系的债务。

8. 在某些情况下不偿还债务

是的,在某些情况下,即使债务很高,也不值得偿还技术债务。这些情况包括原型、证明概念的实现和即将报废的产品产生的技术债务。此外,如果计划为您的传统项目迁移到一个新的技术、平台或架构,不偿还的技术债务是明智的,因为相关的债务可以在迁移过程中解决的。

  1. Ward Cunningham. The WyCash Portfolio Management System, Experience Report, OOPSLA '92.
  2. Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma. Refactoring for Software Design Smells: Managing Technical Debt, Morgan Kaufmann/Elsevier; 2014.
  3. Edith Tom, AybüKe Aurum, and Richard Vidgen. 2013. An exploration of technical debt. Journal of System and Software 86, 6 (June 2013), 1498-1516.
  4. Tool suite for identifying and addressing technical debt. Available online . Last assessed: 27th July 2015. 5.Teamscale. Available online . Last assessed: 27th July 2015.

Tushar Sharma目前是印度班加罗尔西门子技术服务有限公司研究与技术中心的技术专家。他在西门子的工作涉及到软件设计、重构、设计嗅觉、代码、设计质量、设计模和改变影响分析相关主题的研究、咨询和培训。他一直追求自己的研究兴趣,活跃在软件设计和重构领域,并拥有几个专利、研究论文和工具。他有一个印度金奈印度马德拉斯技术学院(iit-m)计算机科学的 MS(通过研究)学位,期间专攻设计模式和重构。他曾合作撰写了两本书;他的第一本书《Oracle Java SE 7 的认证专业程序员考试 1z0-804 和 1z0-805”于 2013 二月由 Apress 出版和第二本书“重构软件设计嗅觉:技术债务管理”由摩根考夫曼出版 2014 十一月。他是 IEEE 高级会员。他的推特是 @ sharma__tushar

Ganesh Samarthyam拥有超过 12 年在 IT 行业工作经验。他是印度班加罗尔 IT 服务初创企业 ZineMindM 的顾问。此前,他曾在班加罗尔西门子公司的软件体系结构和开发团队工作。他的工作涉及向开发团队提供有关代码和设计质量咨询,在软件设计领域不断研究,并进行软件设计与重构和质量驱动的发展相关主题的培训。在西门子工作之前,他在休利特帕卡德的 C + + 编译器团队工作了 5 年,他作为在 ANSI/ISO C++ 标准委员会惠普的代表。他是 IEEE 认证的软件工程认证讲师(SECI)并定期为 IEEE SWEBOK 证书课程培训(SCP)和 IEEE 认证的软件开发(CSDA)程序提供培训。他还帮助为 IEEE SWEBOK 认证程序(SCP)提供课程材料。Ganesh 撰写 / 合著了基本关于编程的书。他推特是 @ gsamarthyam

Girish Suryanarayana目前是印度班加罗尔西门子技术服务有限公司研发中心的高级研究科学家。在西门子,他参与为软件开发团队提供架构指导,从事与软件体系结构和安全相关的主题的研究,并进行内部软件设计和架构培训。现在是 IEEE 软件顾问委员会成员。他积极参与软件工程会议。他是第一次在印度班加罗尔举行的 IEEE 软件专家峰会 2014 次会议大会的主席。在 2013 年,他在软件工程国际会议(第三十五年)是软件工程实践项目委员会(的)成员。Girish 是加利福尼亚大学信息和计算机科学博士。他推特是 @ girish_sur

查看英文原文: Pragmatic Techenical Debt Management


感谢张龙对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2015-10-21 18:185684
用户头像

发布了 32 篇内容, 共 18.0 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

一文了解预训练语言模型!

博文视点Broadview

SMT产线可视化管理,智能工业助力全渠道优化

一只数据鲸鱼

数据可视化 智慧工厂 SMT 智慧工业

架构实战营 模块五作业

netspecial

架构实战营

微博评论的高性能高可用计算架构设计

唐高为

GrowingIO Design 组件库搭建之组件开发

GrowingIO技术专栏

组件

IPFS云算力挖矿系统开发(详情)丨IPFS云算力(源码)案例

系统开发咨询1357O98O718

为什么要做语音聊天室

anyRTC开发者

音视频 WebRTC 语音 RTC

GrowingIO 前端团队对于 GraphQL 的实践总结

GrowingIO技术专栏

大前端 graphql

用了10年Windows后,我最终转向Linux

学神来啦

Linux windows

C 语言面向对象的封装方式(示例)

实力程序员

Redis数据结构

邱学喆

数据库 redis 跳跃表

详解Camtasia的注释功能

淋雨

视频剪辑 Camtasia 录屏

VSPD9.0基础 建立一对互联的虚拟串口,进行串口通信的测试

万里无云万里天

IoT 6月日更 VSPD

“盒模型“初探

编程三昧

CSS css3 大前端 盒模型

玩转容器存储QoS

焱融科技

云计算 容器 云原生 QoS 超融合

《面试官:谈谈你对索引的认知》系列之磁盘I/O

架构精进之路

MySQL 索引结构 6月日更

实现多级缓存架构设计方案

xcbeyond

缓存 缓存架构 6月日更

React Hooks - 如何安全地使用state

蛋先生DX

大前端 React React Hooks JavaScrip 6月日更

中断Hwi:提高鸿蒙轻内核系统实时性及执行效率的秘密武器

华为云开发者联盟

鸿蒙 硬件 中断 鸿蒙轻内核 中断信号

五大新品+两大黑科技,看华为云如何升级基础设施让用户“躺平”

华为云开发者联盟

云原生 基础设施 实景三维建模 计算实例C7 分布式云

vim 操作模式简介

编程三昧

vim 工具

【Flutter 专题】114 图解自定义 ACEProgressPainter 对比进度图

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 6月日更

面试系列-3 限流场景实践

李阿柯

php lua redis 面试 限流算法

BZZ算力挖矿系统开发功能丨BZZ算力挖矿源码设计

系统开发咨询1357O98O718

直击Huawei Mate 40产线背后的华为云IoT智能制造

华为云开发者联盟

IoT 数字化转型 数字孪生 华为云IoT

在Spring Bean实例过程中,如何使用反射和递归处理的Bean属性填充?

小傅哥

Java spring 小傅哥 反射调用 属性填充

有点难的 webpack 知识点:Dependency Graph 深度解析

范文杰

webpack 6月日更

动态规划(详解矩阵连乘 案例+Java代码实现)

若尘

算法 动态规划 矩阵运算 java代码 6月日更

鸿蒙能成为世界第三的操作系统吗?

小智

华为 鸿蒙 操作系统

react源码解析4.源码目录结构和调试

全栈潇晨

React Hooks react源码

论文解读丨空洞卷积框架搜索

华为云开发者联盟

网络模型 目标检测算法 空洞卷积 卷积 空洞卷积框架

  • 扫码添加小助手
    领取最新资料包
务实的技术债务管理_语言 & 开发_Tushar Sharma_InfoQ精选文章