“易于维护的主要特性是局部性:局部性是源代码的特征,它使程序员能够仅查看源代码的一小部分即可理解它。” – Richard Gabriel
行为局部性是这样的原则:
通过仅查看代码单元本身,其行为应尽可能明显
LoB 原则是对 Richard Gabriel 引述语句的简单规范性表述。 在可能的情况下,并与其他关注点平衡,开发者应努力使代码元素的行為在检查时明显。
考虑 HTML 中两种不同的 AJAX 请求实现,第一种使用 htmx:
<button hx-get="/clicked">Click Me</button>
第二种使用 jQuery:
$("#d1").on("click", function(){
$.ajax({
/* AJAX options... */
});
});
<button id="d1">Click Me</button>
在前者中,button 元素的行為在检查时明显,满足了 LoB 原则。
在后者中,button 元素的行為分散在多个文件中。没有对代码库的全面了解,很难确切知道按钮的作用。这种“远程诡异行动” 是维护问题的来源,并阻碍开发者对代码库的理解。
htmx 示例展示了良好的行为局部性,而 jQuery 示例则具有较差的行为局部性。
对行为局部性的常见反对意见是,它将实现细节内联到代码单元中,使代码单元抽象性降低且更易碎。然而,重要的是要区分内联某些行为的实现 与内联某些行为的调用(或声明)。
考虑大多数编程语言中的函数:函数声明与其调用站点使用之间存在区别。一个好的函数会抽象掉其实现细节,但其调用方式也应明显,而不会出现任何远程诡异行动。
增加元素行为明显性的做法,在其他条件相同的情况下,是件好事,但这取决于终端开发者,尤其是框架开发者,使 LoB 既易于实现又概念上尽可能清晰。
LoB 常常与其他软件开发原则冲突。两个重要的原则是:
软件开发者通常努力避免代码或数据中的冗余。这被称为“保持 DRY”,即 Don’t Repeat Yourself。像其他软件设计原则一样,这本身是一件好事。例如,htmx 允许您在 DOM 的父元素上放置许多属性,从而避免在子元素上重复这些属性。这是为了 DRY 而违反 LoB 的情况,开发者需要审慎做出此类权衡。
请注意,行为距离其影响的代码单元越远,违反 LoB 的严重程度就越高。如果它在代码单元的几行之内,这比在一页之外更不严重,而比在完全独立的文件的严重程度更低。
没有硬性规则,而是软件开发者必须做出的主观权衡。
关注点分离是将计算机程序分离成不同部分的设计原则,每个部分处理一个单独的关注点。一个典型的例子是将 HTML、CSS 和 JavaScript 分离。同样,在孤立的情况下,这可能确实是一件好事。最近内联样式变得更加普遍,但在这方面支持关注点分离的论点仍然很强。
请注意,SoC 与 LoB 存在冲突。通过调整 CSS 文件,元素的外观以及在一定程度上行为可能会发生剧变,而且这种剧变来自何处并不明显。工具可以在一定程度上帮助,但仍然存在“远程诡异行动”。
同样,这并不是要全面谴责 SoC,而只是说在考虑如何构建代码时,必须做出主观权衡。最近内联样式变得更加普遍的事实表明,SoC 在开发者中的支持正在减少。
LoB 是一个主观的软件设计原则,可以帮助使代码库更人性化和可维护。它必须与其他设计原则进行权衡,并考虑代码单元所编写系统的限制,但只要实际可行,遵守这一原则将提高您的软件可维护性、质量和可持续性。