软件工程中的海仑定律 - hyrumslaw


海仑定律(Hyrum's Law)是软件工程中一种观察经验:

有了足够数量的 API 用户,
您在合同中承诺什么并不重要:
您系统的所有可观察行为
都将取决于某人。

我(Hyrum)是 Google 的一名软件工程师,致力于大规模代码更改工具和基础架构。在此之前,我花了五年时间改进 Google 的核心 C++ 库。上述观察源于即使是最简单的库更改也会导致某个遥远系统出现故障的经验。
虽然我可能已经做出了观察,但值得称赞的是 Titus Winters 实际上将其命名为“海伦定律(海鲁姆定律/Hyrum's Law)”并更广泛地推广了这个概念。
在过去几年在地球上最复杂的软件系统之一中进行低级基础架构迁移时,我对接口与其实现之间的差异进行了一些观察。我们通常将接口视为与系统交互的抽象(如汽车中的方向盘和踏板),而实现则是系统工作的方式(车轮和引擎)。出于多种原因,这很有用,其中最重要的原因是大多数有用的系统会迅速变得过于复杂,以至于单个个人或团队无法完全理解,而抽象对于管理这种复杂性至关重要。
定义正确的抽象级别是一个完全独立的讨论(参见 Mythical Man-Month),但我们喜欢认为一旦定义了抽象,它就是具体的。换句话说,一个接口理论上应该在系统的消费者和它的实现者之间提供一个清晰的分离。在实践中,这个理论随着系统使用的增长而失效,其用户开始依赖于通过接口有意公开的实现细节,或者他们通过常规使用确定的实现细节。Spolsky 的“抽象泄露法则”体现了消费者对内部实现细节的依赖。
 
隐式接口
从逻辑上讲,这导致了以下观察结果,通俗地称为“隐式接口定律”:如果使用得足够多,就不存在私有实现这样的东西。也就是说,如果一个接口有足够多的消费者,他们将共同依赖于实现的每个方面,有意或无意。此效果用于约束对实现的更改,现在必须符合明确记录的接口以及使用捕获的隐式接口。我们经常将这种现象称为“bug-for-bug 兼容性”。
隐式接口的创建通常是逐渐发生的,接口使用者通常不会意识到它正在发生。例如,一个接口可能不保证性能,但消费者经常期望从它的实现中获得一定水平的性能。这些期望成为系统隐式接口的一部分,系统的更改必须保持这些性能特征才能继续为其消费者发挥作用。
并非所有的消费者都依赖于相同的隐式接口,但如果有足够多的消费者,隐式接口最终将与实现完全匹配。至此,接口蒸发了:实现变成了接口,对它的任何改动都会违背消费者的期望。运气好的话,广泛、全面和自动化的测试可以检测到这些新的期望,但不能改善它们。
隐式接口源于大型系统的有机增长,虽然我们可能希望这个问题不存在,但设计师和工程师在构建和维护复杂系统时考虑它是明智的。因此,请注意隐式接口如何限制您的系统设计和演进,并知道对于任何相当流行的系统,接口的深度都比您想象的要深得多。