_我最初为我的Chainline时事通讯写了以下内容,但我继续收到关于这个想法的推文,所以我在我的博客上重新发布了这篇文章。此版本经过轻微编辑。_。
我一直在思考错误抽象的后果。我在2014年铁路会议上的所有小事都包括了一段我断言的内容:
大得多的演讲中的这一小部分引起了令人惊讶的强烈反应。有几个人说我疯了,但更多的人表达了这样的情绪:
这是它的一百万倍!";@BonzoESC:";重复比错误的抽象";@sandimetz@rbonales pic.twitter.com/3qMI0waqWb";便宜得多。
-41度蓝(@PIMS)2014年3月7日。
强烈的反应让我意识到错误抽象的问题是多么普遍和棘手。我开始问问题,发现了以下模式:
这将创建一个新的抽象。它可以是一个新方法,甚至可能是一个新类。
程序员B觉得保留现有的抽象是有义务的,但是因为不是每种情况都完全一样,所以他们修改代码以接受一个参数,然后添加逻辑以基于该参数的值有条件地做正确的事情。(=
你出现在关于这里的故事里,你的生活发生了戏剧性的转折。
现有的代码具有强大的影响力。它的存在本身就证明了它既是正确的,也是必要的。我们知道代码代表付出的努力,我们非常有动力保护这一努力的价值。不幸的是,不幸的是,代码越复杂、越难以理解,即创建代码的投资越深,我们就越有压力保留它(沉没成本谬论)。这就好像我们的潜意识告诉我们,天哪,这是如此令人困惑,一定花了很长时间才弄清楚。当然,这真的非常重要。如果让所有的努力付诸东流,那将是一种罪恶。
当您在上面的步骤8中出现在这个故事中时,这种压力可能会迫使您继续前进,也就是说,通过更改现有代码来实现新的需求。然而,试图这样做是残忍的。代码不再代表单一的、通用的抽象,而是变成了一个充满条件的过程,其中交织了许多模糊关联的概念。它很难理解,也很容易打破。
如果你发现自己处于这种情况,不要被沉没成本所驱使。在处理错误的抽象时,最快的前进方式是后退。执行以下操作:
在每个调用方中,使用传递的参数来确定此特定调用方执行的内联代码的子集。
这将同时删除抽象和条件,并将每个调用方减少到只需要它所需的代码。当您以这种方式回溯决策时,通常会发现,尽管每个调用者表面上调用了一个共享抽象,但它们运行的代码是相当独特的。一旦您完全删除旧的抽象,您就可以重新开始,重新隔离重复并重新提取抽象。
我见过一些问题,人们勇敢地尝试着用错误的抽象概念前进,但收效甚微。添加新功能非常困难,每一次成功都会使代码变得更加复杂,这使得添加下一个功能变得更加困难。当他们将他们的观点从我必须保护我们在此代码中的投资更改为此代码时,这段代码在一段时间内是有意义的,但也许我们已经从其中学到了所有我们能学到的东西,并允许他们根据当前的要求重新考虑他们的抽象,一切都变得容易了。一旦他们内联了代码,前进的道路就变得显而易见,添加新功能变得更快、更容易。
这个故事的寓意是什么?不要被沉没成本谬论所困。如果您发现自己通过共享代码传递参数和添加条件路径,则抽象是不正确的。一开始可能是对的,但那一天已经过去了。一旦抽象被证明是错误的,最好的策略是重新引入重复,让它告诉你什么是正确的。虽然偶尔积累几个条件条件来洞察正在发生的事情是有意义的,但如果你尽早放弃错误的抽象,你会遭受更少的痛苦。
当抽象错误时,最快的前进方式是后退。这不是撤退,而是朝着更好的方向前进。动手吧。你会改善你自己的生活,也会改善所有跟随你的人的生活。
我的下一个公共实用面向对象设计课程将于2018年5月2-4日在北卡罗来纳州的达勒姆举行。是的,现在是另一个POODNC的时候了。这是你与志同道合的同龄人共度三天的机会。加入我们,改变您对物品的看法。
99瓶OOP已完成,1.0.1版本现已面市。这本书由卡特里娜·欧文(Katrina Owen)联合授权,历经数年痛苦而艰苦的制作。了解更多信息,阅读扩展样本,阅读独立评论,或者立即购买。