2002年Joel Spolsky探讨抽象泄漏法则:开发工具中的抽象复杂性

2025-04-05
来源:网络整理

在2002年的这篇文章中,联合创始人乔尔(Joel)探讨了抽象泄漏的定律。他指出,许多开发工具致力于通过抽象来简化我们的工作流程,以隐藏其背后的复杂性。

但是,尽管抽象旨在掩盖潜在的复杂性,但这些复杂性通常在实际应用中暴露出来。这主要是由于抽象本身的固有复杂性以及实施过程中遇到的各种问题。人们强调的是,尽管抽象可以节省我们的工作时间,但并不能减少必须投资的学习时间。

01互联网工程中的抽象

您每天都有一些互联网工程中的神奇机制。该机制发生在TCP()协议中,该协议是构建的基础之一。

TCP提供了传输数据的可靠方法。这意味着:如果您通过网络通过TCP发送消息,则将准确地传递。我们依靠TCP完成许多任务,例如获取网页和发送电子邮件。正是由于TCP的可靠性,每本电子邮件都可以完美地到达,即使只是一些无聊的垃圾邮件。

相反,还有一种称为IP()的数据传输方法,这是不可靠的。没有人保证您的数据会到达,并且可能会在此过程中受到干扰。如果您通过IP发送一系列消息,请不要惊讶,其中只有一半可以到达,有些可能会乱七八糟,有些可能会被其他内容替换,其中可能包含可爱的小大猩猩图片,或者更有可能与您收到的外国垃圾邮件相似的一堆不可读的内容。

这是一个神奇的地方:TCP建立在IP上。也就是说,TCP需要依靠本质上不可靠的工具来实现可靠的数据传输。

想象一下,我们有一种方法可以通过将他们送入汽车来驾驶美国,从百老汇到好莱坞。一些汽车事故造成了演员的悲惨死亡。有时,演员们在路上喝醉,剃光头或在鼻子上纹身,​​无法在好莱坞工作。而且,由于他们选择了不同的路线,因此演员通常不会按原始计划的顺序到达。

现在想象一下,一项名为 的新服务,承诺在演员时交付:(a)安全到达(b)保持正确的顺序(c)状况良好。

魔力是,没有比用汽车在全国驾驶好莱坞快车更可靠的方式。取而代之的是,通过确认每个演员都完整到达,如果有任何问题,请与演员在总部发送的同卵双胞胎联系。

如果演员不一致,那么好莱坞快车将重新订购。如果一个巨大的不明飞行物在内华达州的高速公路上坠毁,将路线封锁,所有经过的演员都会转移到亚利桑那州,而好莱坞快车将不会告诉加利福尼亚电影导演有关这些变化。对于导演来说,演员的到来比平时慢一点,他们甚至永远都不知道不明飞行物的撞车事故。

这是TCP的魔力。这就是计算机科学家所说的“摘要”():简化复杂基础操作的一种方法。

02抽象漏洞

小程序开发缓慢隐藏元素_让元素隐藏的代码_实现元素隐藏

实际上,许多计算机编程工作都涉及抽象的构建。什么是字符串库()?它使处理字符串与处理数字一样简单。什么是文件系统?它使我们觉得硬盘不是存储位的旋转磁盘积累,而是一个层次结构的文件夹系统,每个文件都由一个或多个字节字符串组成。

回到TCP的主题。我以前告诉过一些谎言,以简化问题,并可能使某些人感到不高兴。我说TCP可以保证消息传递,但事实并非如此。如果您的宠物蛇从计算机的网络电缆上叮咬,导致IP()数据包无法传输,则TCP将无法使用,并且您的信息将无法传递。

如果您对公司的系统管理员不友好,他们可能会通过将您连接到重负载中心来惩罚您,以便只有一部分IP数据包才能成功传输,而TCP仍然会尝试工作,但一切都会变得非常慢。

这正是我所说的“抽象泄漏”()。 TCP试图提供涵盖基本不可靠网络的完整抽象;但是,有时网络的实际问题渗透到了这种抽象,使您感到抽象无法完全掩盖的问题。这只是我称为“抽象泄漏法则”的众多示例之一:

所有复杂的抽象在某种程度上都有漏洞。

抽象有时会有问题。有时问题不是很大,有时候问题很严重。这称为“泄漏”。在使用抽象的过程中,错误是不可避免的。这是一些例子。

03开发中常见的抽象泄漏

一个看似简单的操作,例如在大型二维阵列上穿越,如果您选择水平而不是垂直进行性能,则可以具有很大的性能差异。这就像木材的纹理方向一样,系统错误的数量(页故障)可能是由不同的遍历方向引起的,这可能会减慢程序的速度。通常假定编写基础程序代码的汇编语言程序员也可以操作大型,平坦的内存空间。但是,由于存在虚拟记忆,这只是一个理论思想。当出现页面错误时,此抽象会揭示出漏洞,而某些内存访问的时间比其他内存更多。

SQL语言旨在简化数据库查询过程中所需的特定步骤。它允许您仅定义所需的结果,并且数据库自动确定如何专门执行它。但是,在某些情况下,某些SQL查询可能比逻辑上的其他问题要慢数千倍。一个众所周知的示例是,在某些SQL服务器上,如果指定“ A = B和B = C和A = C”,则查询速度的速度将比仅指定“ A = B和B = C”的速度要快得多,即使最终结果集相同。从理论上讲,您不需要关心特定的查询过程,只能关注所需的结果。但是有时,该抽象层会出现问题,从而导致严重的性能降解。目前,您可能需要使用查询计划分析仪(计划)来检查问题并找到加快查询的方法。

虽然NFS(文件)和SMB()等网络库使您在远程机器上以本地文件的形式处理文件,但有时网络连接可能会变得非常缓慢或直接断开连接,这使得文件无法像本地文件一样操作。作为开发人员,您需要编写代码来处理这种情况。 “远程文件作为本地文件”的抽象具有漏洞。这是UNIX系统管理员的特定示例。如果将用户的主目录设置在通过NFS安装的驱动器(抽象)上的驱动器上,则用户创建a。文件以将所有消息转发到其他地方(另一个抽象),当NFS服务器到达时,NFS服务器失败时。 。无法找到文件。这个抽象的漏洞实际上导致了一些电子邮件的丢失。

C ++字符串类的最初意图是使字符串处理简单,就好像字符串是基本数据类型一样。这些课程试图隐藏字符串处理的复杂性,使操纵字符串像操纵整数一样简单。几乎所有C ++字符串类超载加号(+)运算符,允许您简单地用S+“ Bar”拼接字符串。但是存在一个问题:无论这些类有多么努力,当前没有C ++字符串类直接支持“ Foo”+“ bar”直接用于剪接字符串,因为在C ++中,字符串文字实际上是char*类型,而不是字符串对象。这揭示了语言级别的漏洞,语言设计本身无法解决。 (有趣的是,C ++的历史可以看作是不断尝试修补此字符串抽象漏洞的过程。至于为什么不直接将本地字符串类添加到语言中,我不知道为什么。)

即使您的汽车配备了雨雨,大灯,屋顶和加热器,这些设备也可以帮助您忽略多雨天气的直接影响(它们试图抽象天气因素),您仍然无法像下雨的晴天一样驾驶。这是因为您需要考虑到车辆滑动的风险,有时雨太重了,前方的视线非常有限,迫使您放慢脚步。因此,天气的实际影响永远无法完全忽略,这正是抽象泄漏定律所描述的现象。

04抽象泄漏的挑战

让元素隐藏的代码_实现元素隐藏_小程序开发缓慢隐藏元素

抽象泄漏定律的一个问题是,它并没有真正简化我们的生活。例如,当我教新手成为C ++程序员时,我希望他们不必了解复杂的char*和指针操作。我希望直接教他们如何使用STL的字符串类。但是,当他们尝试执行诸如“ foo” +“ bar”之类的操作时,该程序将出乎意料地行事,在这一点上,我必须解释与char*相关的所有复杂细节。或者,当他们需要调用API函数时,该函数的文档表示其具有类型的输出参数,他们在了解多个概念(例如char*,和 )之前无法正确调用此功能。这些基本的细节和概念是所谓的“泄漏”,它们不断地浮出水面,挑战了抽象的原始意图 - 简化的编程。

如果我只需要向他们展示如何使用向导和各种代码生成工具,那将是多么棒。但是,一旦出现任何问题,他们通常会对发生的事情,如何进行调试和修复感到困惑。因此,我不得不详细地向他们解释诸如(班级标识符),(程序标识符)等核心概念……这确实是对人性的折磨!

在教授ASP.NET编程时,理想的情况是,我只需要告诉学生双击元素,并编写一些代码,这些代码将在用户单击这些元素时在服务器端执行。 ASP.NET实际上简化了编写HTML代码的差异,该代码处理超链接()点击和按钮点击。但是,问题是ASP.NET设计人员需要隐藏以下事实:在HTML中,超链接本身不能用于提交表单。为了解决此问题,他们生成了一些代码,并将单击事件处理程序()添加到超链接中。但是,这种抽象存在漏洞。如果禁用最终用户,则ASP.NET应用程序将无法正常工作。如果程序员不了解哪些细节ASP.NET抽象,他们将不知道什么问题。

和想法

抽象泄漏的定律表明,每当出现新的代码生成工具可以大大提高效率时,您总是会听到许多人建议:“学会先手动操作,然后使用这些高级工具节省时间。”这些代码生成工具试图简化所有抽象,总是有一些缺陷。有效地处理这些缺陷的唯一方法是了解这些工具如何工作以及它们试图简化的内容。

因此,尽管这些工具可以减少我们的工作量,但它们并不能减少我们的学习时间。所有这些都表明了一个矛盾:尽管我们拥有更高级的编程工具和更精致的抽象方法,但成为熟练的程序员的困难正在增加。

在的第一次实习期间,我负责为计算机编写字符串库。一个典型的任务是编写函数的变体,该函数将指针返回到新字符串的末端。这只需要几行C代码。我所依赖的所有知识都来自一本简单的书,由“ C”撰写和撰写。

今天,要处理它,我需要掌握一系列高级工具,包括COM,ATL,C ++,内部机制,正则表达式,DOM,HTML,CSS和XML。这些都是相对于旧K&R材料的高级工具,但是我仍然必须熟悉K&R的基础知识,否则我已经完成了。

十年前,我们可能会认为新的编程范式可以使编程变得更加容易。的确,多年来我们开发的抽象技术使我们能够处理软件开发之前尚未遇到的复杂问题,例如图形用户界面(GUI)编程和网络编程。这些功能强大的工具(例如现代面向对象的形式的语言)使我们能够快速完成很多工作。但是,突然之间,我们可能会出于抽象漏洞引起的问题,并且解决该问题可能需要两个星期。此外,当您需要聘请主要从事VB编程的程序员时,仅VB编程技能就不够了,因为每当VB的抽象层出现问题时,它们可能会感到无助。

抽象泄漏的定律正在拖累我们的发展。

分享