AHA编程原则

·  阅读 100
AHA编程原则

无意中发现了一篇关于编程理念的博文,感觉挺好的,分享出来给大家。
原文地址:kentcdodds.com/blog/aha-pr…
原作者:Kent C. Dodds
作者首先阐述了已有的两种编程原则:DRYWET,对这两种原则进行了辩证讨论,然后引出了自己提出的编程原则:AHA。虽然对WET的抨击我不太认同,但是为了文章完整性,我也把这部分内容写了出来。

DRY

DRY (an acronym for "Don't Repeat Yourself"), 是一个经典的编程原则,维基百科对她的总结是:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system
在一个系统中,每一个知识都必须有一个单一的、明确的、权威的表示

不写重复的代码!不能简单的Ctrl+C/Ctrl+V,这也是我非常赞同的一种好的编程方法。Ctrl+C/Ctrl+V的一个最大坏处是如果这段代码存一个bug,那么你将不得不在所有复用到它的地方进行修复。当你想要Ctrl+C/Ctrl+V时请想到一句话:所有你开发阶段偷的懒,在维护阶段都将加倍偿还!
在这里作者也给出了一个自己的亲身经历:

Once, I inherited a codebase that made very heavy use of code duplication and one time I had to fix a bug in eight different places! 😱 Talk about irritating! Abstracting that code into a function that could be called anywhere it was needed would've helped out a LOT.
有一次,我继承了一个大量使用代码复制的代码库,有一次我不得不在八个不同的地方修复一个bug !😱真是令人恼火!将代码抽象成一个函数,可以在任何需要的地方调用它,既能达到复用目的,也不会出现重复编写的问题。

WET

WET(Write Everything Twice),这是另一个被人们称为WET的编程概念,意思是“把所有东西都写两遍”(但是绝不写第三遍!!!)。这是该原则的原文:

You can ask yourself "Haven't I written this before?" two times, but never three.
你可以问自己“我以前是不是写过这个?”两次,但绝对不要有三次

这个原则主要想表达的编程理念是:不要过早的优化代码,不要过早的抽象,而是允许重复几次类似的代码。
它契合了开发者本能的反应,当开发一个功能时我们会本能地问自己,这个功能我以前开发过吗?已有的代码能够复用吗?这里的“复用”是基于已有代码经过了完成测试和实际使用,是验证过的“正确”代码。所以“复用”其实是基于正在查看的确切实现而做出更加准确的开发决策。
比如,你正在构建一个web应用程序,你可能想要将你的按钮抽象成一个组件,因为你将使用大量的按钮。但是,如果有一个具有某些特殊样式的页面(比如含有跟业务紧密耦合的特殊图表),那么就不需要对该页面上的组件进行抽象。事实上,在这个系统下,如果需要一个类似于那个特殊页面的新页面,可以直接复制/粘贴并更改所需的代码。
然而,当这种情况发生第三次时,就需要花点时间抽象出可以抽象的部分。并且,在完成抽象后请再做一件事:

You must comment your abstractions
你必须为你抽象的代码添加注释

每当您抽象出某些内容时,您都是在对应用程序的映射进行重新排列组合,是对代码逻辑的一次扰乱。如果你没有添加注释来说明你进行抽象的前因后果,那么这段抽象代码将是难以维护的,你就是在给你的团队挖坑(也包括你自己)。

PS:这段建议我太赞同了!并且亲身经历告诉我,凡是在开发中觉得复杂的逻辑都添加必要的注释,因为这段逻辑后续还将由你维护,除非你记忆力超群,否则没有注释你根本不知道当初为啥这样写,不给自己挖坑!

AHA

AHA (发音: "Aha!") 是Avoid Hasty Abstractions的缩写,中文释义是:避免草率的抽象。 作者认为自己对这一原则的看法被sandy Metz完美地描述了,sandy Metz写道:

prefer duplication over the wrong abstraction
宁愿重复也不要错误的抽象

这是一个非常有价值的智慧,sandy在自己的一篇博文中有完整的阐述:Wrong Abstraction。写得非常好。 在sandy的博文之外,作者补充的另一个重要的相关原则是:

Optimize for change first
变更优化优先

作者认为编程的一个关键特征是开发者不知道代码的未来会是怎样的。开发者可能会花费数周的时间优化代码的性能,或者为自己的新抽象设计出最好的API,结果第二天发现自己做了错误的假设,API需要完全重做,或者编写代码的功能不再需要了。因为这些不确定的因素存在。
开发者所能确定的是:功能可能会改变,如果功能从来没有改变,那么开发者就不会碰代码,更不会去修改,所以谁在乎它看起来像什么呢?

不要误解作者的意思,作者并不是在暗示任由代码混乱。作者只是建议开发者应该注意这样一个事实,即开发者并不真正知道将来对代码的要求是什么。代码的功能将会改变,而这一切是不可预知的。

所以作者对代码复制没什么意见。直到你非常有信心知道重复代码的清晰逻辑,代码的各个部分的差异,哪些可以抽取为函数,哪些可以作为参数从外部传入? 当你在一些地方运行相同的代码时,功能共性会更好让你思考如何进行抽象,你就会有正确的心态来提供这种抽象。

关于提前抽象,作者是这样说的:

If you abstract early though, you'll think the function or component is perfect for your use case and so you just bend the code to fit your new use case. This goes on several times until the abstraction is basically your whole application in if statements and loops 😂😭
如果你提早抽象化,你会认为功能或组件对你的用例来说是完美的,所以你只需要修改代码来适应你的新用例。然后这些修改这将进行好几轮,直到最后,你会发现抽象的结果是基本上是整个应用程序充斥着if-else和循环😂😭

作者认为“AHA编程”的最大好处是,让开发者不再时刻纠结是否要编写抽象/抽取公共代码,而是专注于功能开发,知道“感觉正确的时候”才进行逻辑抽象。在进行逻辑抽取的时机未到来之前,不要害怕复制代码。

PS:那什么时候才是进行逻辑抽象的“正确时候”呢?参考DRYWET原则自行体会。

参考

Stop trying to be so DRY, instead Write Everything Twice (WET)
AHA Programming

分类:
代码人生
标签:
分类:
代码人生
标签: