匈牙利统治






3.47/5 (22投票s)
很有可能你听说过,或者甚至告诉过别人,不要使用匈牙利命名法。很有可能,你自己就在使用它。匈牙利命名法是命名约定的王者。尽管许多人呼吁其消亡,但它依然存在。
什么是匈牙利命名法?
对于不熟悉匈牙利命名法的人来说,它是一种命名约定,将项的数据类型、预期用途或其他元信息纳入项名中。许多人对匈牙利的理解很狭隘,并对其使用表示反对。但正如你将看到的,匈牙利不仅仅是“strName”,而且在不久的将来也不会消失。
史前
匈牙利命名法可以追溯到计算的黎明时期,并且正式的定义可以追溯到 80 年代。它最初在类型不明确的语言中用于管理键入,并且在我们只有简单的编辑器而不是信息丰富的 IDE 时得到了普及。
在 C 等语言中,我们可以通过声明来明确变量类型,例如
int x = 0; string y = "Hello";
Basic 等语言不允许显式类型声明,而是使用“let”和“var”等关键字进行声明。
let x = 0 var y = "Hello"
根据语言的不同,设置 x = y 可能会导致错误,或者成功地得到 x 变为 'H',或者 72(H 的 ASCII 码)等结果。
早期
开发人员通过在字符串变量后附加“$”来实现最早的“类型安全”形式。这在当时只有两种数据类型(数字和字符串),并且解释器和编译器无法强制执行时很有帮助。
let x = 0 // x is a number let y$ = "Hello" // y is a string
为了保持一致性,% 后缀在某些区域也用于表示数字。随着语言的成熟和附加数据类型的可用,需要另一种方法。匈牙利命名法的最早形式建立在后缀方法之上。这并非风格上的选择,许多人更喜欢类型优先的方法,而是 BASIC 语言的技术限制。BASIC 语言当时正成为最流行的通用计算语言。
早期的 Basic 版本只支持两个字符的变量名。虽然后来版本允许八个字符的名称,但内部只使用了前两个字符——“so”和“some”是同一个变量。采用像 C 和 FORTRAN 这样的声明类型语言中使用的 [类型][名称] 顺序(例如,string :: y)是不可能的——strX 和 strY 在内部是同一个变量——st。
我猜想,剩余的六个字符是第一个句法糖——对程序员有用,但对计算机无意义。使用剩余六个字符的方法有助于催生另外两个最终普遍存在的编程概念——匈牙利命名法和元数据。
围绕如何使用这六个“多余”字符,形成了许多思想流派。它们可以分为三大类——它是**什么**,它是**什么类型**,以及**如何使用**它。“它是什么”流派基本上是清晰命名——使用额外的空间来阐明项的“真实世界”名称。人名从“na”变为“name”。“类型”方法使用空间来指示内部存储类型。Name 是一个字符串,所以——“nastr”。“如何使用”有许多变体。一些今天仍以某些形式存在的例子是可变性和作用域。常量“name”可能是“nacon”,或者局部变量可能是“naloc”。这将演变成变量可见性(例如,_name 表示私有变量)。
形式化
多年以后,变量名的长度限制消失了。清晰命名只是健全编程实践的一部分。元命名方法已转向更接近 C 风格的前缀和基于类型的方法——strName 将是上面示例的常规形式。意图驱动的命名并未被放弃,但正在失去青睐。后缀也是如此。面向对象编程的出现一定程度上带回了两者。在一个笛卡尔坐标系中,我们可能会发现一个点的 x 和 y 坐标被命名为 fltXPoint 和 fltYPoint。或者为了表示返回整数的函数名称,我们可能会看到 intSumFn。
关于形式化这些约定的许多工作发生在 80 年代后期。这项工作中一些最知名的名字是 Charles Petzold、Doug Klunder 和 Charles Simonyi。其中,Simonyi 影响最大,如果仅仅是因为匈牙利这个名字源于 Simonyi 的匈牙利血统。Simonyi 的影响力远远超出了为这个名字做贡献。Simonyi 是 MS Word 和 Office 的创始人,并在该组织中标准化了匈牙利命名法的用法,最终传播到微软的所有产品。匈牙利命名法的标准形式被定义为三个部分——标签、基本名称和限定符。
形式化产生了两种主要的匈牙利命名法——应用程序匈牙利法和系统匈牙利法。它们主要在标签的使用方式上有所不同。应用程序匈牙利法使用存储类型前缀(strName)作为标签。系统匈牙利法则更注重用途,有两种常见方法——colorBackground(系统用途)或 m_Background(作用域)。M 代表“成员”,通常用于表示私有变量或属性的后备变量。m_ 在代码中非常普遍,以至于许多人删除了 m,而只使用了 _。限定符用于扩展语义。常用的限定符有 min、max、first 和 last 等——intRangeMin 和 intRangeMax。一种替代形式使用了较旧的“元类型限定符”方法——intBackgroundColor。
Visual Basic
随着语言的进步,大多数语言都支持变量的类型声明。IDE 提供了更好的类型可见性(Intellisense),使得应用程序匈牙利法不太有用。但 Visual Basic 的流行增加了匈牙利的整体使用。Visual Basic 的结构通常将“可视化”窗体文件与后备代码文件关联起来。代码文件通常响应窗体中“控件”引发的事件。使用匈牙利命名法通过在变量前加上控件类型来维护这些文件之间的链接,这已成为一种标准方法。我们大多数人都熟悉 btn_Accept 或 txt_FirstName。限定符与事件相关联。按钮点击事件的处理程序被命名为 btn_Accept_OnClick()。基本名称为“Accept”,标签为“btn”,限定符为“Click”(OnClick)。
VB(和 ASP)中构建窗体的 GUI 方法由代码生成器支持。为了保持语义命名并避免潜在的名称冲突,生成器通常会将控件类型附加到控件名称。用于名字的文本框将收到名称 FirstNameTextBox,以避免与用户变量 txt_FirstName 冲突。按钮可能是 AcceptButton。这种形式的系统匈牙利法是反向的,被称为“反向匈牙利法”。
那么,匈牙利命名法是什么?
我们可以看到,匈牙利命名法不仅仅是“strName”——typeVariable,甚至不是 [Tag][BaseName]。任何使用 [Tag][BaseName][Qualifier] 变体的名称,包括反向的 [Qualifier][BaseName][Tag],都是匈牙利名称。而且,虽然一种常见形式(应用程序匈牙利法)使用存储类型(例如 int)作为标签,但其他形式(系统匈牙利法)则不使用。在线词典对匈牙利命名法给出了以下定义:
“匈牙利命名法是计算机编程中的一种标识符命名约定,其中变量或函数的名称指示其意图或种类,而在某些方言中则指示其类型。”
将此定义与许多人在被问及定义匈牙利命名法时可能说的话进行对比。也许——
“匈牙利命名法是在变量名前加上其数据类型缩写的前缀。”
第一个定义了匈牙利命名法,第二个只定义了一种使用标签和基本名称的应用程序匈牙利法,并省略了限定符。
今天的匈牙利命名法
快进到今天。你是否进行 DI,并将本地注入的变量命名为类似“_context”?这是匈牙利命名法。IInterface、iInterface 或 i_Interface?匈牙利命名法。你使用 ASP.Net MVC 吗?整个 MVC 基于约定的系统都是匈牙利命名法。你的控制器被命名为 SomethingController 吗?匈牙利命名法(反向)。异步?如果你在异步方法后附加 Async,你就在使用匈牙利限定符。应用程序匈牙利法(例如 strName)在现代编程中的价值很小,我认为应该避免使用它。但是,如果我们消除了所有匈牙利命名法的使用,还有什么选择呢?匈牙利命名法自 80 年代以来一直是我们的命名约定,并且在可预见的未来仍将是我们的标准。匈牙利命名法已死,匈牙利命名法万岁!