← 返回规律列表
架构

抽象必漏

任何有实际意义的抽象都会在某种程度上“泄漏”,暴露底层实现细节。

显示原始英文内容

The Law of Leaky Abstractions

All non-trivial abstractions, to some degree, are leaky.

Takeaways

  • No matter how well-designed, abstractions (libraries, frameworks, etc.) have edge cases that depend on internal details.
  • Developers should understand that using a high-level tool doesn't absolve them from knowing what's happening underneath, at least at a basic level.
  • "Leaky" means you might encounter performance issues, bugs, or behavior that force you to consider the underlying system (e.g., networking, OS) on which the abstraction sits.
  • When creating abstractions, strive to minimize leakage and document the cases in which it might break.

Overview

This law observes that in complex systems, the abstractions we create, meant to hide complexity, *inevitably fail in some scenarios*, revealing the underlying complexity to the programmer.

For example, consider an ORM (object-relational mapper) that lets you treat database entries as objects. Most of the time it works, but occasionally you hit a case where performance is terrible and you have to think about the SQL queries being generated. The abstraction "leaks" details of the database.

The law isn't saying abstractions are bad. They are essential. But it reminds us that one must be prepared for when they break.

Examples

A good example is memory management in high-level languages. Languages like Java and Python abstract away manual memory allocation thanks to garbage collection. Yet leaks still happen (objects not being freed due to lingering references), or you encounter the abstraction's limits (such as GC pauses affecting performance). Suddenly, the developer needs to know how garbage collection works internally, and the abstraction of "infinite memory" has leaked.

Web developers often treat an HTTP request as something fast, abstracting away the network. However, when latency spikes or packets drop, the network's reality leaks into your application.

Origins

Joel Spolsky introduced this law in a 2002 blog post. He gave examples such as TCP (which abstracts reliable connections over IP, but on a bad network the abstraction leaks, causing timeouts) or the virtual memory abstraction.

The concept resonates with many earlier thoughts in computing, essentially a restatement of "there's no free lunch" with abstractions.

核心含义

抽象的目标是隐藏复杂性,但网络延迟、数据库索引、文件系统限制、事务边界等底层事实,迟早会通过性能、错误或特殊行为暴露出来。抽象并没有消灭复杂度,只是改变了它出现的位置。

好的抽象不是假装底层不存在,而是在合适的层次暴露必要的约束,并让异常情况有清晰的解释。

实践例子

一个 ORM 让开发者可以使用对象操作数据库,但当查询变慢、出现 N+1 查询或需要事务控制时,开发者仍必须理解 SQL、索引和连接池。

来源与边界

这个概念由 Joel Spolsky 推广。它不主张放弃抽象,而是提醒团队为性能、故障和调试保留逃生通道与底层知识。