所谓“技术债务”,是指过去犯下的错误,最终需要通过重构来弥补。那么开发者该如何分辨哪些才是良好的技术债务呢?

作者 | Jon Thornton

译者 | 弯月,责编 | 郭芮

出品 | CSDN(ID:CSDNnews)

以下为译文:

在软件工程领域中,“技术债务”是一个贬义词。人们在使用这个词的时候常常表达出某种遗憾,过去犯下的错误,最终需要通过重构来弥补。

然而,金融债务却没有遭遇到众口一词的谴责。比如你的朋友抵押贷款够买了新房子,你会说什么?肯定会说:“恭喜!”债券是基础设施和公共事业标准的融资形式。企业使用了各种债务,而华尔街却对股价上涨充满了信心。

技术债务与金融债务之间的不同之处在于意图——如果技术债务也并非总是意外,或者由错误的假设和意外情况导致,那会怎么样?你会如何处理技术债务的贷款呢?

如果我们将技术债务定义为将来必须完成的工作,那么就可以根据将来所需要花费的工作时间来计算开销。我们也可以选择现在就“投入”时间来完成这些工作。

这种心理上的模型可以帮助我避免浪费开销,或承担起力所不及的系统维护工作,同时也让我有机会看到有目的性地使用技术债务的机会。在以下几个案例中,我借助技术债务取得了项目的成功。

脚手架

在划分某个大项目主要功能的优先级时,通常我会首先验证项目中最具风险性的部分。这里的风险我指的是最容易出错的部分,因为这些部分很复杂、难以定义、未得到充分的理解,或者让我嗅到了“危险的气息”。由于这些是最艰难的部分,所以我会赶在代码库尚小且容易扩展的时候,首先构建这些部分。

然而,仅仅构建有风险的组件还远远不够。我需要知道构建这些有风险组件的方式是否正确。然而,实践才能出真知,所以我会全力推动我的代码进入现实世界。这也就意味着我需要在构建应用程序的其余部分之前,找到一种方法有效利用这部分有风险的代码。

在我们团队开发电子邮件营销活动时,我们首先需要构建电子邮件编辑器。我们拥有顶级的设计和强大的内容编辑工具,我们希望构建一流的应用程序。几个月后,我们兴冲冲地向同事们展示了我们的编辑器,但当时我们还没有构建实际发送电子邮件的系统。如果这个编辑器只是一个无法发送电子邮件的玩具,那么我们就无法获得真实的反馈。

最终的产品需要快速可靠地发送数亿封电子邮件,但我们不需要立即实现这个功能。

所以,我们问自己:“怎样才能通过最简单的方式鼓励我们的同事使用这个编辑器?”当时我们公司有几百名员工,而且内部的测试人员可以容忍这个编辑器的不稳定性。与我们一直在考虑的健壮系统相比,构建一个发送几百封邮件的不稳定系统肯定会容易很多。于是,我们意识到我们可以构建一个廉价的应用程序,即便日后丢弃了也不可惜,目的只是为了快速获取用户的反馈,这就成了我们的脚手架系统。

如下自我实施的指导方针帮助我们顺利地实现了这个脚手架系统:

  • 严守预估的工时。如果我们无法在预定的时间范围内完成脚手架系统,那么就表明我们承担了过多的工作,需要重新考虑实现方法。

  • 从一开始就明确传达,这个系统会被抛弃。代码需要很好地封装,而且我们也没有浪费时间来讨论实现细节。

  • 我们明白脚手架的局限性,因此有意避免在故障会造成伤害的情况下使用脚手架。如果我们花时间清理脚手架造成的错误,那么必将带来更深入的债务,所以我们小心翼翼地测试脚手架的使用情况。

  • 利益相关者知道我们在有意承担债务。我们在利益相关者和用户前面夸大了这个系统的限制,告诉他们这些只是为了节约时间,而且在这个过程中确保他们知道之后我们需要投入时间来构建真正的电子邮件发送系统。

我们利用这个脚手架填补了依赖项空缺,目的是为了调整应用程序的构建顺序,确保尽早验证应用程序,同时又不会遇到构建组件的问题。

当代码在我们脑海中记忆犹新的时候,我们丢弃的电子邮件发送系统收获了很多有关电子邮件编辑器的反馈意见,这帮助我们加快了迭代的速度,并完善了我们的难题。当构建真正的电子邮件发送系统时,我们从脚手架系统的构建中吸取了大量经验。

硬编码

最近,我正在开发一个产品的仪表板,其中有一个功能是在某个区域显示最新的消息,比如:“祝所有订阅者节日快乐!”我们团队需要每隔一个月或两个月刷新仪表板在该区域显示的内容。

我们需要一个内容管理系统(CMS),我们的产品经理和设计人员可以通过这个系统自行更新仪表板上的消息。此外,产品经理还希望仪表板能在特定时间点更新,而工程师不希望为了响应这些需求而定时手动更新生产版本。

一种方法是构建数据库支持的CMS,帮助我们团队的各个成员在无需工程师干预的情况下,自行更新仪表板上的内容。

然而,这种方法的成本很高:额外的前端、验证以及数据管理。这些隐藏的成本是沉重的技术债务,将来必然给开发人员带来更多的维护工作,相比这个功能就得不偿失了。此外,仪表板上的消息内容可以持续数周而无需更新,因此即时更新内容的解决方案对我们并没有好处。

因此,我们没有采用会带来额外开销的基于数据库的CMS,而是将我们的内容存储在YAML文件中,并重用现有的工具来提供CMS功能。更新仪表板消息传递的用户界面不一定非要用浏览器界面,也可以是文本编辑器和Git。其他团队成员可以通过代码审查来验证这些更新,因此我们不需要花时间编写验证和错误处理程序。我们现有的CI工具可以跨环境自动同步内容更改。

为了实现在特定时间发表新内容,我们编写了更多的硬编码,如下所示:

if now >= NEW_CONTENT_DATE(新内容的日期)show new content(显示新内容)
elseshow old content(显示旧内容)

在采用硬编码时,我考虑了以下几个因素:

  • 这些更新需要几个小时才能生效吗?硬编码有一个明显的限制:这些更新的新代码需要部署到生产中。如果没有意识到这个限制,那么可能会引发棘手的维护问题,从而产生恶劣的技术债务。

  • 用户愿意接受Git的这个新界面吗?每个更新都需要与团队版本控制工具以及CI系统交互。为了避免更多的协调或培训的开销,我们测试了一下:参与这个过程的人中是否有人了解Git?

  • 是否有现成的UI、验证和数据模式?硬编码可以避免定义新模式,从而获得最大受益。如果应用程序现有的模式可以彻底解决问题,那么就不值得使用硬编码。

通常,下面这些设计模式都可以考虑使用硬编码:权限列表、表单字段选项和功能开关等。

无需修复所有的边缘案例

我曾经构建的一个功能允许用户创建最多10个项目,但不允许超过10个。这里面包含一个很常见的竞争条件:如果我们同时发出两个创建项目的请求,那么这两个请求都会计算现有的项目数,然后同时创建两个项目。如果此时我们已有9个项目,那么最终就会创建11个项目——超过了我们的限制。

大多数测试人员会认为这是一个bug,而bug是用户可见的技术债务。

在这种情况,我们本可以利用数据库事务解决这个问题,但我们使用的数据库是不支持事务的NoSQL。读/写锁都没问题,但我们需要在分布式系统中运行,因此需要分布式锁。如果我们编写一堆锁定代码来实现这种“完美”的限制,那么最终可能会引入其他意外的bug。而且我们必须花大量时间编写一堆锁定代码,而且之后的每位开发人员都必须理解这段锁定代码。

似乎我们付出了这么多努力只是为了不会多创建一个项目。那么非技术性的解决方案呢:如果我们故意不修复这种竞争条件,会怎么样?

我说的可不是对这个问题视而不见,留给下一位开发人员来处理!我说的“故意”是说搞清楚以下几个问题:

  • 如果创建了11个项目,那么会怎么样?嗯,实际上也没什么大不了。这是一个很武断的限制,应用程序的其余部分并不在意多出来的几个项目。

  • 我们可以了解一下这种竞争条件的发生频率是否高于预期?也就是说,通过一条数据库查询找出超过10个项目的账号,且每条项目记录都有一个时间戳。结果却发现生产环境中并没有这种竞争条件。

因此,我们大可以不必理会这笔技术债务。由于创建额外项目的影响很小且易于监控,我们可以将时间花在优先级更高的工作上,无需在这种不是问题的问题上浪费时间。

对于良好的技术债务要做到心中有数

许多沉重的技术债务都是因为构建的功能过多,而且花在维护和改bug上的时间超过了预期。这就好像你购买了太多地产,最终陷入溺水屋的困境(注:按揭买房者所欠银行的钱超过房子本身的价值)。

关键在于你清楚投入的时间,并了解你所承担的成本。由于构建的功能太少而引发的问题并不可怕,因为你随时可以构建更多功能。我们应该构建方便丢弃和替换的功能,这样代码会更加模块化。良好的技术债务的局限性很明显,且众所周知。你可以在代码的注释、README、常见问题解答以及与人的对话中澄清这些局限性。

你可以善加利用良好的技术债务,将时间集中在重要的工作上,加快构建软件的速度。

原文:https://engineering.squarespace.com/blog/2019/three-kinds-of-good-tech-debt

本文为CSDN翻译,转载请注明来源出处。

【END】

Python0基础到实战

https://edu.csdn.net/topic/python115?utm_source=csdn_bw

 热 文 推 荐 

☞和 Python 2.x 说再见!

那些年 iOS 升级踩过的坑!

AI 落地谁最强?AI Top 30+案例评选等你来秀

☞Google 警告开发者:所有 Android App 需要三天的审核时间!

漫画:程序员等级图鉴

☞如何用知识图谱挖掘商业数据背后的宝藏?

☞福利 | 送你一张通往「2019 AI开发者大会」的门票

92年小哥绞尽脑汁骗得价值800万比特币, 破案后警方决定还给受害者

☞微服务架构到底是什么鬼?

☞如何写出让同事无法维护的代码?

点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

你点的每个“在看”,我都认真当成了喜欢

@程序员,欠下的技术债怎么还?相关推荐

  1. 那些年我们程序员欠下的技术债

    2019独角兽企业重金招聘Python工程师标准>>> 前言 关于这个问题其实在心里酝酿了很久,直到女票发来一篇文章,简单扫了一眼.第二天清晨,灵光一现,突然就有了这么一个标题. 我 ...

  2. 代码质量与规范,那些年你欠下的技术债

    提到"质量"二字时,我们的第一反应往往是"有多少BUG?""性能好不好?"这样的问题.我们对软件产品或服务的质量定义看其能不能满足用户的需求 ...

  3. 阿里淘系程序员“开源”内部年度技术总结,还把P9大佬喊出来教你“打怪升级”...

    鱼羊 发自 凹非寺 量子位 报道 | 公众号 QbitAI 什么?阿里淘系程序员的年度技术总结,竟然是我可以免费看的东西? 不仅有P9大佬"现身说法"专讲如何从P4到P9升级打怪. ...

  4. 阿里资深技术专家:在各阶段中,3年经验的程序员应具备哪些技术能力(进阶必看)...

    3年工作经验的Java程序员应该具备哪些技术能力,这可能是Java程序员们比较关心的内容.我这里要说明一下,以下列举的内容不是都要会的东西,但是你掌握得越多,最终能得到的评价.拿到的薪水势必也越高. ...

  5. 程序员可以只关心技术么?

    摘要:不少程序员爱维护喜欢的技术,虽然他们说的有道理,但程序员价值的实现并不取决于技术.模式不一样,程序员价值也不一样,而这也暗含了程序员生涯的两个进阶模式,读完此文,相信你会重新思考个人生涯发展方向 ...

  6. 程序员该如何学习技术

    程序员该如何学习技术 前言   学习是第一生产力,我从来都是这么认为的,人只有只有不断地学习才能意识到自己的缺点和不足,身为程序员,我更认为人们应当抱着终身学习的想法实践下去,这是我所一直践行且相信的 ...

  7. 程序员如何积累编程技术或编程经验?

    工作中总是被问到程序员如何积累编程技术或编程经验?首先我认为编程是一门实践性的很强的艺术,所以貌似唯有实践才能积累.然而把它当作一个个人软件过程(PSP)的问题,总感觉是有一些规律.规则或建议可以解答 ...

  8. 为什么高级程序员不必担心自己的技术过时?

    程序员是吃青春饭的吗?等我们老了,技术过时了,公司有什么理由不裁掉我们,去雇一些既有活力.薪资要求又低的年轻人呢?这个老生常谈的问题困扰着诸多渐入中年的程序员.本文告诉你如何增强自己的核心竞争力,在知 ...

  9. 知乎高赞回答:为什么高级程序员不必担心自己的技术过时?

    高赞回答:为什么高级程序员不必担心自己的技术过时? 这些软技能都有可能成倍地增加我们工作的影响力(作为个人贡献者和技术负责人).软技能包括: 代码审查礼节: 如何优雅地遏制范围蔓延: 如何向其他部门直 ...

最新文章

  1. PHP生成PDF文档的FPDF类
  2. hash算法_一致性hash算法简介
  3. 添加非oracle用户到dba, oinstall组
  4. centos环境变量设置
  5. pytorch加载预训练 加载部分参数
  6. rssi室内定位算法原理_三分钟看懂蓝牙室内定位 值得分享
  7. Telerik RadGridView动态增删行及行列操作
  8. 【原创】分布式之redis复习精讲
  9. 把旧系统迁移到.Net Core 2.0 日记(1) - Startup.cs 解析
  10. 大数据基础知识问答----hadoop篇
  11. 在TOC中添加右键查看属性信息菜单
  12. html 监听后端变化_SpringBoot2.0整合WebSocket,实现后端数据实时推送!
  13. 如何使用chevereto自建图床
  14. BSC智能链主网节点搭建-2022最新详细版文档
  15. 只有1kb的清理软件_教您清理1kb快捷方式病毒
  16. spark写入Oracle 报错 java.lang.ArrayIndexOutOfBoundsException: -32423
  17. 达梦数据库(DM8)基本使用
  18. IPv4地址不够怎么解决
  19. cmd命令行下怎样切换目录
  20. 常用开发工具 之 SQLite 数据库 与 Navicat for SQLite 的下载、安装与简单使用说明

热门文章

  1. Hive(Impala)测试数据生成与加载
  2. Spark UI无法查看到slave节点
  3. 《Linux编程》作业 ·002【Shell编程】
  4. 由alpha matte生成trimap
  5. 【0xC1900101】BOOT过程中的SAFE_OS阶段安装win10失败的解决方法
  6. n皇后问题c语言报告,关于N皇后问题
  7. opencv-python 鼠标事件和坐标点截图
  8. TensorFlow GAN项目程序回顾2020.12.03
  9. 电子计算机之争的想法,模拟意识的通俗讲解
  10. linux rps值大小,Linux系统中RPS/RFS介绍