消除“代码重复”是绝大部分程序员矢志不渝追寻的目标。而在本文中,我们通过引入“代码重复”来解决开发中常见的需求变化。
美国知名的软件工程师Sandi Metz曾经说过一句很经典的话:
代码重复比错误的抽象伤害更小。(duplication is far cheaper than the wrong abstraction)
或者说:
宁可代码重复,也不要错误的抽象。(prefer duplication over the wrong abstraction)
“错误的抽象”问题是非常普遍和棘手。我们经常在工作中发现下面的场景:
现存的代码具有强大的影响力。它的存在本身就表明它是正确的和必要的。我们知道代码代表了所花费的工作,并且我们非常有动力去保存这项工作的价值。不幸且可悲的事实是:代码越复杂、越难以理。也就是说,在创建代码时投入越多,我们就越会有保留这些代码的压力(“沉没成本谬误”)。就好像我们的潜意识告诉我们:“天哪,这么如此让人迷惑,一定花了很长时间才弄好。这些代码必然非常非常重要。让所有的努力付诸东流将是一种罪过。”
沉没成本谬误:人们往往不愿意正视持续增加投资未必会带来更多回报的事实,而选择铤而走险地持续对过去投资失败的项目增资,以逃避过去投资失败带来的反悔心理。
当你出现在上面的第8步时,这种压力也可能会迫使你继续前进,也就是说,通过更改现有代码来实现新的需求。然而我们面临的残酷的现实是:代码不再代表一个单一且通用的抽象,而是变成了一个包含条件的过程,其中交织着许多模糊关联的思想。它很难理解且很容易打破。
如果你发现自己在这种情形下,不要被沉没成本所驱使。在处理错误的抽象时,最快的前进方法是回退。做以下几点:
通过这样做消除了抽象和条件,并将每个调用者减少到仅它需要的代码。 当你以这种方式回顾决策时,通常会发现虽然每个调用者表面上调用了一个共享抽象,但他们运行的代码却独一无二。 一旦你完全删除了旧的抽象,你就可以重新开始,重新隔离重复代码并重新提取抽象。
在工作中人们勇敢地尝试以错误的抽象方式前进,但收效甚微。 添加新功能变得非常困难,每次成功都会使代码更加复杂,这使得添加下一个功能更加困难。 当他们将观点从“我必须保留我们对这些代码的投入”转变为“这些代码对解决以前的问题是有阶段性意义的,但也许我们已经从中学到了我们所需要的一切”,接着根据当前需求重新思考它们的抽象,一切都变得更容易了。 一旦代码被放回调用者,前进的道路就变得显而易见,添加新功能变得更快、更容易。
故事中的场景的寓意是什么? 不要被沉没成本谬误所困! 如果你发现自己通过共享代码传递参数和添加条件路径,则标明抽象是错误的。 也许这个抽象一开始可能是对的,但那一天已经过去了。 一旦抽象被证明是错误的,最好的策略是重新引入代码重复,让它告诉你什么是正确的。 虽然偶尔积累一些条件语句以深入了解正在发生的事情是有意义的,但如果你早点放弃错误的抽象,你会遭受更少的痛苦。
当抽象错误时,最快的前进方式就是回退。 这不是退缩,而是朝着更好的方向前进。这样做, 你不仅将改善自己的工作,也会改善所有追随者的工作。
参考资料:
https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction
页面更新:2024-05-01
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号