技术债务真正的代价

无论你是否喜欢把它想成技术债务或是对冲期权,在我们的周围都充斥着糟糕的代码,糟糕的决定,以及这些东西给我们每天的生活带来的影响。但是这些决定所带来的长期影响会是什么?我们真的做了明智的选择吗?Martin Fowler谈论了技术债务的四种类型:从鲁莽的、故意的到偶然的、谨慎的。

故意不计后果的债务

故意不计后果的技术债务就是这样的:开发者(或者他们的经理)会允许那些只可能带来坏结果不可能带来好结果的决定被通过—例如,放弃TDD或者不用任何设计。无论从什么角度来看,这种做法都是非常不专业的。如果开发人员不能做出正确的选择,那么管理者就应该介入,并带入一些能够做明智选择的人进来。 Michael Norton将这称为“令人讨厌的行为,而不是技术债务”。如果我们不能从中受益,并且只是简单地完成任务,写一些糟糕代码,那么这根本不是技术债务,这是垃圾。

The true cost of technical debt 2

不易察觉的债务

不易察觉的技术债务比较有趣。如果我们不知道有更好的东西,我们又怎么会去做一些改变呢?工业标准和最佳的实践都在不断发展。我确定曾经某段时间EJB被认为是很好的组件模型,但现在它绝对被认为是不折不扣技术债务。当前的最佳实践方式很容易就变成未来的垃圾代码。

当开始时,如果我们就已经有了这个领域的知识,或者可能我们从未在这个领域工作过,没有这个领域的知识,可能设计出来的东西会不太相同。有些时候技术债务是不可避免和必然发生的。

谨慎故意的债务

接下来是谨慎而有意的技术债务,这种情况下,我们会有意做一个决定来增加技术债务。这里就有一个再普通不过的决定:

“不管怎样,我们要达到这个季度的目标利润。

我们的市场工作已经开始,所以我们必须在短的时间内抢占市场。

我们已经承诺了交货日期,所以没有太多时间给我们去犯错误。”

有时,我们必须做一些妥协:通过降低工作成果的品质,我们可以更快的完成工作,但我们会稍晚时候付出代价。

不同于其它的技术债务,这是一种特殊的技术妥协。我们故意做决定让代码质量比我们能够达到的质量要差。我们知道这会在以后让我们慢下来;我们知道我们需要回来重做,在所谓的“二期工程”里完善它;但是为了在规定的时间内完成任务,我们接受妥协。

它始终都是正确的决定吗?

1.妥协在短期来看更快,但在长期来看其实更慢

在我们现在就需要的东西与后续可能产生的不明的债务之间做选择时—显而易见,我们始终都会选择妥协。

2.每个妥协都看似渺小,但它们积累起来却非常庞大

不管有多少人都经历过“欠债”,技术债务都会积累起来。我们所做的每次妥协都会增加已有债务的代价。这意味着,每次妥协的代价可能很小,但积累起来后它们会产生巨大的影响。

一开始,我决定不重构一些代码。下一轮时,由于没有很好的重构,很难测试代码,所以我跳过了一些单元测试。第三轮时,我的测试覆盖率非常低,所以我没有信心进行扩展性重构。现在,这段程序真的变得很难测试也很难修改。我的代码在一点一点地,越来越快地恶化。每个妥协都堆积在以前的妥协之上,而且将它们放大。每次妥协看似影响很小,但它们累加起来却让人大伤脑筋。

The true cost of technical debt 1

3.长期的代价很难被量化

当我们同意不重构一段代码时,当我们同意留下一些半成品时,当我们同意为了急于通过测试而采用最小测试项时:这真的很难去估计长期的代价。当然,我们能够估算如何做是正确的—我们知道什么是“真理”。但是,我们如何去估计成本的支出?特别是当它们积累起来时。

我怎么能估计为了解决复杂问题而浪费的时间?时间的损失有可能是因为一个非常难以追查的bug。额外花费的时间可能是因为下一次我无法很容易地重构代码;或者是因为下一次我不敢重构代码,但额外的债务使我不得不这样去做。我怎么可能去量化这个问题?

在IMVU,他们发现他们:

“至少低估了一个量级的技术债务的长期代价”

它始终都是错误的吗?

这里有一些很明显的例子,它们都在产生技术债务;或者至少做得有些不称职。如果你想在客户面前展示一个新特性以判断其是否有价值,那么它不需要很完美,它只需要迅速地出现在那里就行。如果新特性对客户没用,那么你将其删除。你节省了将其做“完美”的成本,并迅速获得了你所需要的信息。这显然是符合成本控制的,是一种管理开发过程的简易方式。

The true cost of technical debt 3

但是,如果展示的这个特性获得成功了呢?那么,你需要制定一个计划清理它,重构它,确保它产生足够的文档并被充分的测试。这就是债务。只要你有一个删除它的计划,无论这个特性是有用或无用—那么这是一个完美而有效的方式。但如果不是这样,那么这个半成品特性可能需要数年时间去构建代码。

不同的是,我们会有一个计划来消除债务。多久我们就会接受一个模糊的承诺“我们会回过头来修复它”,或者,“我们会在第二阶段完善它”。我的墓志铭应该是“现在开始第二阶段的工作”。

在代码中留下债务,且没有任何消除债务的计划,就像一个家伙用一张信用的钱去还另一张信用卡的钱。你让债务产生,而不去处理它。没有偿还债务的计划,你最终将走向破产。

技术债务的风险

也许技术债务最大的危害是它代表的风险。技术债务使得我们的代码更加脆弱,不太容易修改。当我们最近讨论这个问题时,正如@bertvanbrakel所说:

“技术债务会使代码变得僵化”

在我们代码上堆积的债务越多,代码就越难改变。这种僵化会带来最大的风险:我们无法足够快速地改变代码。如果竞争环境和监管环境突然变化?如果一个新的竞争对手出现,彻底改变了我们的行业,我们需要多久才能赶上?如果我们只有一个僵化的代码库,在我们花2、3或4年时间赶上竞争对手时,我们又能得到什么呢?

当然这是指的最坏的情况,这种灵活性的缺失(缺乏创新)会一点一点地损害公司。一旦一个革命性的公司变成老古板,无法作出反应,并只释放衍生产品。当公司发现自己无法创新,跟不上不断变化的局势—它们就会变得无关紧要。这也就是技术债务真实的代价。

没有一个偿还技术债务的计划,没有可靠的办法来估计它所带来的长期成本,我们真的可能做出谨慎而故意的决定吗?这种轻易就能增加技术债务的决定做得是否太草率了呢?


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/451350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 8 Stream的性能到底如何?

Java 8提供的流的基于Lambda表达式的函数式的操作写法让人感觉很爽,笔者也一直用的很开心,直到看到了Java8 Lambda表达式和流操作如何让你的代码变慢5倍,笔者当时是震惊的,我读书少,你不要骗我。瞬间我似乎为我的Serve…

“docker-app”实用工具分享,大大提高 Compose 文件复用率

本文首发自“Docker公司”公众号(ID:docker-cn)编译丨小东每周一、三、五 与您不见不散! Docker Compose 在开发人员中非常流行,它用来描述应用程序。目前,GitHub 上有超过30万个 Docker Compose 文件。通过…

bootstrap-validator 验证一个标签同时验证另一个指定标签

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 如图 验证 str_atBeginDate 同时把 str_atTermDate 也作一次验证: 注意 红框中 " value “ 不能少,我之…

solr基本查询和高级查询

查询参数常用: q - 查询字符串,必须的。fl - 指定返回那些字段内容,用逗号或空格分隔多个。start - 返回第一条记录在完整找到结果中的偏移位置,0开始,一般分页用。rows - 指定返回结果最多有多少条记录,配…

Angular4 存储访问路由栈信息

一、实现方法1.可以通过路由守卫,可以给父级路由添加,若无父级路由,则需要每个路由都需要添加守卫,即每个页面都需要调该方法例如:jdb-app端上的tool.service.ts是每个页面都会调取的方法,可以将监听路由函…

python基本语法:字典

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 一、数据类型和对应符号: 元组 ( ) 列表 [ ] 字典 { } 二、字典是python中唯一的映射类型(哈希表&#xf…

JavaScript实现向OL列表内动态添加LI元素的方法

2019独角兽企业重金招聘Python工程师标准>>> <script type"text/javascript"> function addItem() {var myitem document.getElementById("ItemToAdd").value;var mylistItems document.getElementById("mylist");var newP …

【blockly教程】第五章 循环结构

在这里&#xff0c;我们将介绍一个新游戏--Pond Tutor 在Pond Tutor(https://blockly-games.appspot.com/pond-tutor)这个游戏中&#xff0c;我们将扮演黄色的鸭子&#xff0c;通过不断的发炮弹去攻击红色的鸭子&#xff0c;当红色的鸭子血条减为0时则玩家获胜。在这个游戏中为…

360董事长周鸿祎跨足手机市场是福还是祸?

编者按&#xff1a;奇虎360董事长周鸿祎做的这个“思考了半年”的决定&#xff1a;进军智能手机&#xff0c;是于5月4日夜10时45分。他所发布新浪微博称&#xff1a;“现在每个人都想拥有高性能的智能手机&#xff0c;高富帅白富美人手一iPhone&#xff0c;难道吊丝只能买便宜低…

3 .6 .5 优化Ad-Hoc工作负载

执行计划生成后会存储在plan cache中&#xff0c;以便重用&#xff0c;如果计划缓存从来都没有被重用 过&#xff0c;将会造成内存资源的浪费&#xff0c;这有可能是由于非参数化的Ad-hoc (即席查询&#xff09;引起的。 当执行代码时&#xff0c;会产生一个hash值&#xff0c;…

表单隐藏域与display:none

有时候前端进行表单填写是分步骤的&#xff0c;每一步的时候其他步骤相关的表单视图不可见&#xff1b; 针对"不可见"&#xff0c;以下有两种处理方式&#xff1a; ①display&#xff1a;none 这种方式呢&#xff0c;比较简单&#xff0c;就是将三个步骤分3个div&…

视频领域的Instagram:Viddy用户突破2600万

北京时间5月9日消息&#xff0c;据TheNextWeb报道&#xff0c;视频分享应用Viddy的注册用户数量已经达到2600万&#xff0c;而上个月的用户数量还是650万。日均增长用户超过50万&#xff0c;成绩斐然&#xff0c;投资者对Viddy目前的增长表示很满意。 Viddy是如何达到这样的成…

2018年7月份,python上传自己的包库到pypi官网的方法

最近pypi官网进行了更新&#xff0c;老的上传网址作废了。记录下上传到pypi的方法 0、去pypi官网注册账号&#xff0c;没账号是不可能上传的&#xff0c;想想也是那不乱套了吗&#xff0c;注册后会收到一个邮件需要点击然后重新登录 1、目录就是这样 &#xff0c;我要上传muli…

写给大数据开发初学者的话2

见 : http://lxw1234.com/archives/2016/11/782.htm 如果你已经按照《写给大数据开发初学者的话》中第一章和第二章的流程认真完整的走了一遍&#xff0c;那么你应该已经具备以下技能和知识点&#xff1a; 0和Hadoop2.0的区别&#xff1b;MapReduce的原理&#xff08;还是那个…

Pandas的结构和应用

Pandas处理以下三个数据结构 - 系列(Series)----一维ndarray   特点&#xff1a;带有标签&#xff0c;可以使用标签作为索引&#xff0c;大小不能改变&#xff0c;内部数据可以改变。 属性&#xff1a;与NumPy类似&#xff0c;多了一个轴标签axis lables 数据…

时间即财富:创业者浪费精力的八个错误

导读&#xff1a;本文作者Jeff Miller是美食网页应用Punchfork的创始人&#xff0c;同时也是DuckDuckGo、Ginzametrics、Art.sy、DataMinr以及Forkly的投资人。作者通过对自己创业初期一些错误选择进行盘点&#xff0c;告诉读者在创业初期应该学会选择&#xff0c;因为在创业初…

写给大数据开发初学者的话3

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 如果你已经按照《写给大数据开发初学者的话2》中第三章和第四章的流程认真完整的走了一遍&#xff0c;那么你应该已经具备以下技能和知识…

十五周二次课

18.6 负载均衡集群介绍 主流开源软件LVS、keepalived、haproxy、nginx等其中LVS属于4层&#xff08;网络OSI 7层模型&#xff09;&#xff0c;nginx属于7层&#xff0c;haproxy既可以认为是4层&#xff0c;也可以当做7层使用keepalived的负载均衡功能其实就是lvslvs这种4层的负…

写给大数据开发初学者的话4

见&#xff1a;http://lxw1234.com/archives/2016/11/795.htm 如果你已经按照《写给大数据开发初学者的话3》中第五章和第六章的流程认真完整的走了一遍&#xff0c;那么你应该已经具备以下技能和知识点&#xff1a; 为什么Spark比MapReduce快。使用SparkSQL代替Hive&#xff…

域名解析服务之DNS查询类型

在实际应用中DNS查询主要分为两种方式查询&#xff1a;1.递归查询&#xff1b;2.迭代查询 一般情况下&#xff1a;为了减少资源的消耗&#xff0c;网络中客户端与所属的本地DNS服务器查询方式通常为递归查询&#xff0c;本地DNS服务器与外部的公共DNS服务器间的查询方式为迭代查…