内容简介:复制比错误的抽象便宜得多(代价小成本低),宁可重复而不选择错误的抽象。让人们意识到“错误的抽象”这个问题是很难:现有代码会产生强大的影响力。它存在的本身会被认为它既正确又必要。我们知道代码代表了努力的付出,我们非常积极地保持这种努力的价值。
复制比错误的抽象便宜得多(代价小成本低),宁可重复而不选择错误的抽象。
让人们意识到“错误的抽象”这个问题是很难:
- 程序员A看到重复。
-
程序员A提取重复并为其命名。
这创建了一个新的抽象。它可能是一种新方法,甚至可能是一种新类。
-
程序员A用新的抽象替换了复制。
啊,代码很完美。程序员A快乐地走开了。
- 时间流逝....
- 出现了一个新的需求,当前的抽象几乎是完美的。
-
程序员B负责实现此需求。
程序员B感到很荣幸能够保留现有的抽象,但由于每种情况都不完全相同,他们会改变代码来获取参数,然后添加逻辑以根据参数的值有条件地做正确的事情。
曾经的通用抽象现在对不同的情况有不同表现了。
- 另一个新需求来了。程序员X. 再另加一个附加参数和另一个新条件,如此循环直到代码变得难以理解。
- 你出现在这里的故事中,你的生活发生了戏剧性的转折。
现有代码会产生强大的影响力。它存在的本身会被认为它既正确又必要。我们知道代码代表了努力的付出,我们非常积极地保持这种努力的价值。
不幸的是,令人遗憾的事实是,代码越复杂和难以理解,即创建它的投入越深,我们就越感到继续保留它会产生很大压力。(“ 沉没成本谬误 ”)
这种压力可能迫使您继续前进,即通过更改现有代码来实现新要求。然而,试图这样做是残酷的。代码不再代表单一的,共同的抽象,而是成为一个条件负载的过程,它交织了许多模糊相关的想法。它很难理解,也很容易破碎。
如果你发现自己处于这种状况,就要抵制沉没成本的驱使。在处理错误的抽象时,最快的前进方法就是返回。请执行下列操作:
- 将抽象代码放回每个调用者,重新引入重复的代码。
- 在每个调用者中,使用传递的参数来确定此特定调用者执行的内联代码的子集。
这将删除抽象和条件,并将每个调用者减少到它们只需要的代码。
过去的代码虽然每个调用者表面上都调用了共享抽象,但他们运行的代码却相当独特。一旦完全删除旧的抽象,您就可以重新开始,重新隔离重复并重新提取抽象。
人们正在勇敢地尝试以错误的抽象方式前进,但收效甚微。添加新功能非常困难,每次成功都会使代码变得更加复杂,这使得添加下一个功能变得更加困难。
当他们改变他们的观点时,“我必须保持对这段代码的投资”,“这段代码有一段时间才有意义,但也许我们已经从中学到了所有东西”,并允许自己重新思考根据当前的要求抽象,一切都变得容易。一旦他们内联代码,前进的道路变得明显,添加新功能变得更快更容易。
如果您发现自己传递参数并通过共享代码添加条件路由时,则抽象是不正确的。
(banq注:抽象出的代码里如果有if前置条件判断,说明逻辑的默认前置条件被破坏,抽象是错误的)
一旦抽象被证明是错误的,最好的策略是重新引入重复并让它向您展示什么是正确的。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Golang学习笔记之错误处理error、panic (抛出错误),recover(捕获错误)
- c – 构建PBRT v2错误 – 错误1错误U1077:’if’:返回代码’0x1′
- !错误!在 Android 下这么用 ShowModal 是错误的!
- Google开源ClusterFuzz:使得查找错误并修复错误变得异常简单
- 脚本错误量极致优化-定位压缩且无 SourceMap 文件的脚本错误
- php – 解析错误:语法错误,意外’未设置'(T_UNSET)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。