发布于 2026-01-06 9 阅读
0

Abstraction DEV 的全球展示挑战赛由 Mux 赞助:展示你的项目!

抽象

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

开发者经常谈论抽象。例如:

抽象的目的不是为了含糊其辞,而是为了创造一个新的语义层面,在这个层面上可以做到绝对精确。

——艾兹格·迪克斯特拉

或者

宁可重复劳动,也不要错误的抽象。

——桑迪·梅茨

或者

我们如何创建抽象层来隐藏特定 UI 部分的实现细节?

——丹·阿布拉莫夫

此外,丹在一条推文中提到了“抽象阶梯”。我在之前的文章中使用了“抽象塔” 。开发者们所说的“抽象”究竟是什么意思?

什么是抽象?

抽象,是指将许多事物中观察到的共同特征或关系提取出来,或称之为“抽象”的认知过程,或者说是这种过程的产物。
被抽象出来的对象——即抽象概念或抽象对象——有时被认为是一种概念(或“抽象思想”),而不是一种属性或关系。

——大英百科全书

我还查阅了牛津词典韦氏词典斯坦福英文词典,但它们并没有提供太多帮助。

更简洁的定义是——抽象是去除细节过程的产物。注意,它并没有具体说明要去除哪些细节,以及为什么要去除,又是如何去除的。这是一个相当宽泛的定义,程序员使用“抽象”一词时,它可以指代很多不同的概念。让我们来看看。

抽象模型

当我们需要在应用程序中表示真实(或非真实)对象时,我们通常只选择一些我们关注的属性(细节)。这种表示方法称为建模。我们只关注一些选定的细节,而忽略其他细节,这就是抽象。

例如:在关系数据库中将实体建模为表,在面向对象编程中将实体建模为类,在高级类型系统中将实体建模为类型

抽象即实现细节的隐藏

当我们构建某个 API、接口或契约,并隐藏其具体实现方式时,我们就可以在不修改 API 的情况下更改实现。我们隐藏实现细节,例如将其移除,也就是进行抽象。

例如:高级语言抽象掉了硬件层面实现的细节;关系数据库以 SQL 的形式公开 API,我们不需要知道它在底层使用了哪些算法和数据结构就可以使用它。

有时抽象会隐藏不同的抽象,因此我们有多层抽象,也称为抽象之塔或抽象之梯。

如果我们仍然需要了解其底层实现方式,这就被称为“抽象泄漏”。例如,关系数据库中的索引通常用 B 树实现,这就是为什么查询速度LIKE abc%LIKE %abc很慢的原因。

抽象作为一种概括

我们只需关注群体中的某些共同细节,就能将群体归入同一类别,并对整个群体做出判断。我们忽略了不常见的细节,进行了抽象。

正如你所见,我们选择关注哪些细节,会影响我们最终会归入哪个群体。从这个意义上讲,抽象是一种视角。

例如:面向对象编程(继承)层次结构中的基类;

问题在于定义过于宽泛

正如我们所见,在软件开发中很多事物都可以被视为抽象概念,这可能会让人感到困惑(我认为)。我们需要区分不同类型的抽象吗?它们是相似的,还是只是看起来相似?我不知道。

抽象错误

我们有时会听到“错误的抽象”这样的说法。那么,究竟是什么让抽象变得错误(或糟糕)呢?错误的抽象是指我们选择关注错误的细节。例如,当两段代码语法相似(例如,看起来相似),但目的未必相同时——在这种情况下引入抽象可能是一个很大的错误(桑迪·梅茨(Sandi Metz)也谈到了这一点)。

当我们说“关注错误的细节”时,我们需要理解“错误”取决于具体情况。当上下文发生变化时,例如,引入了新的需求,而我们原有的抽象概念不再适用于新的上下文时,抽象概念最终可能会变得不准确。

抽象思维

抽象思维超越了软件开发范畴,它是一种认知过程。抽象思维和范畴思维一样,都有其弊端,我们需要意识到这一点。

不同的事物看起来可能相似。

当我们进行抽象思考时,我们可以选择一组特定的细节,使不同的事物看起来相似。例如,摩天轮和汽车,两者都有轮子,都可以乘坐,但只有汽车可以用来从一个地方移动到另一个地方。

相似的事物看起来可能不同

当我们进行抽象思考时,我们可以选择一组特定的细节,使相似的事物看起来截然不同。例如,鲸鱼与海胆的亲缘关系比与鲨鱼的亲缘关系更近。

不同的人可以选择不同的抽象概念。

抽象就像坐标系——它可以任意选择,因此,这可能会造成混乱。

延伸阅读

文章来源:https://dev.to/stereobooster/abstraction-1987