是否值得学习该约定,或者它是否会影响可读性和可维护性?

有帮助吗?

解决方案

考虑到大多数人使用 匈牙利表示法 正在遵循它的误解版本,我想说这是毫无意义的。

如果你想使用它的原始定义,它可能更有意义,但除此之外它主要是语法糖。

如果您阅读了 维基百科文章 在这个主题上,你会发现两种相互矛盾的符号, 系统匈牙利表示法匈牙利表示法.

原来的好定义是 匈牙利表示法, ,但大多数人使用 系统匈牙利表示法.

作为两者的示例,请考虑为变量添加前缀 l(表示长度)、a(表示面积)和 v(表示体积)。

有了这样的表示法,下面的表达式就有意义了:

int vBox = aBottom * lVerticalSide;

但这并没有:

int aBottom = lSide1;

如果您混合前缀,它们将被视为等式的一部分,并且体积 = 面积 * 长度对于盒子来说很好,但是将长度值复制到面积变量中应该会引发一些危险信号。

不幸的是,另一种表示法不太有用,人们在变量名前加上值的类型作为前缀,如下所示:

int iLength;
int iVolume;
int iArea;

有些人使用 n 代表数字,或 i 代表整数,f 代表浮点数,s 代表字符串等。

最初的前缀是用来发现方程中的问题的,但不知何故已经转变为使代码更容易阅读,因为您不必去寻找变量声明。在当今的智能编辑器中,您只需将鼠标悬停在任何变量上即可找到完整类型,而不仅仅是其缩写,这种类型的匈牙利表示法已经失去了很多意义。

但是,你应该自己做出决定。我只能说我两个都不用。


编辑 只是添加一个简短的通知,虽然我不使用 匈牙利表示法, ,我确实使用了前缀,它是下划线。我为类的所有私有字段添加前缀 _ ,并以其他方式拼写它们的名称,就像属性一样,标题首字母大写。

其他提示

如果正确使用,匈牙利命名惯例会很有用,但不幸的是,它往往被误用。

阅读乔尔·斯波尔斯基的文章 让错误的代码看起来错误 以获得适当的观点和理由。

本质上,基于类型的匈牙利表示法,其中变量以有关其类型的信息为前缀(例如对象是否是字符串、句柄、整数等)几乎没有什么用处,并且通常只会增加开销而几乎没有什么好处。遗憾的是,这是大多数人都熟悉的匈牙利表示法。然而,匈牙利表示法的目的是添加有关变量包含的数据“种类”的信息。这允许您将不同类型的数据与其他类型的数据分开,这些数据不允许混合在一起,除非可能通过某些转换过程。例如,基于像素的坐标与基于像素的坐标其他单位的坐标,或不安全的用户输入与来自安全来源的数据等。

这样看,如果您发现自己在代码中寻找有关变量的信息,那么您可能需要调整命名方案以包含该信息,这就是匈牙利约定的本质。

请注意,匈牙利表示法的替代方法是使用更多的类来显示变量使用的意图,而不是到处依赖原始类型。例如,您可以为不安全的用户输入使用简单的字符串包装类,并为安全数据使用单独的包装类,而不是为不安全的用户输入使用变量前缀。在强类型语言中,这样做的优点是由编译器强制执行分区(即使在不太强类型的语言中,您通常也可以添加自己的 tripwire 代码),但会增加不小的开销。

当涉及到 UI 元素时,我仍然使用匈牙利表示法,其中多个 UI 元素与特定对象/值相关,例如,

lblFirstName 为标签对象,txtFirstName 为文本框。我绝对不能把他们俩都命名为“FirstName”,即使 是两个对象的关注/责任。

其他人如何命名 UI 元素?

它毫无意义(而且令人分心),但在我的公司中使用相对较多,至少对于整数、字符串、布尔值和双精度类型而言。

sValue, iCount, dAmount 或者 fAmount, , 和 bFlag 到处都是。

曾几何时,召开这个会议是有充分理由的。现在,它是一种癌症。

我认为匈牙利表示法是通向更具可读性的代码的“路径”上的一个有趣的脚注,如果做得正确,比不做更好。

不过,我宁愿废除它,而不是这样:

int vBox = aBottom * lVerticalSide;

写这个:

int boxVolume = bottomArea * verticalHeight;

现在是 2008 年。我们不再有 80 个字符的固定宽度屏幕了!

另外,如果您编写的变量名称比您应该考虑的要长得多的变量名称重构为对象或函数。

很抱歉提出一个问题,但是在接口上添加“I”前缀是否符合匈牙利表示法?如果是这样的话,那么是的,很多人在现实世界中使用它。如果没有,请忽略这一点。

我认为匈牙利表示法是一种规避我们短期记忆能力的方法。根据心理学家的说法,我们可以存储大约 7 加减 2 块 的信息。通过包含前缀添加的额外信息可以帮助我们提供有关标识符含义的更多详细信息,即使没有其他上下文也是如此。换句话说,我们可以猜测变量的用途,而无需查看它是如何使用或声明的。这可以通过应用面向对象技术来避免,例如 封装单一职责原则.

我不知道这是否已经过实证研究。我假设,当我们尝试理解具有超过 9 个实例变量的类或具有超过 9 个局部变量的方法时,工作量会急剧增加。

如今,范围不是比类型更重要吗?

  • l 本地
  • 一个用于论证
  • m 代表会员
  • g 代表全球
  • ETC

使用重构旧代码的现代技术,由于更改了符号的类型而搜索和替换符号是乏味的,编译器会捕获类型更改,但通常不会捕获范围的错误使用,明智的命名约定在这里有所帮助。

当我看到匈牙利的讨论时,我很高兴看到人们认真思考如何使他们的代码更清晰,以及如何使错误更加明显。这正是我们都应该做的!

但不要忘记,除了命名之外,您还可以使用一些强大的工具。

提取方法 如果您的方法变得太长,以至于您的变量声明已经滚动到屏幕顶部之外,请考虑使您的方法更小。(如果您有太多方法,请考虑一个新类。)

强类型 如果您发现您正在服用 邮政编码s 存储在整数变量中并将它们分配给 鞋号 整数变量,考虑为邮政编码创建一个类,并为鞋码创建一个类。然后你的错误将在编译时被捕获,而不需要人工仔细检查。当我这样做时,我通常会发现一堆邮政编码和鞋号特定的逻辑,我将它们散布在我的代码中,然后我可以将其移至我的新类中。突然间,我的所有代码都变得更加清晰、简单,并且免受某些类别的错误的影响。哇。

总结:是的,认真思考如何在代码中使用名称来清楚地表达您的想法,但也要考虑您可以调用的其他强大的 OO 工具。

我没有使用非常严格意义上的匈牙利表示法,但我确实发现自己在一些常见的自定义对象上使用它来帮助识别它们,而且我倾向于在 gui 控件对象前面加上它们的控件类型。例如,labelFirstName、textFirstName 和 buttonSubmit。

我对按钮、文本框和标签等 UI 元素使用匈牙利命名。主要好处是在 Visual Studio Intellisense 弹出窗口中进行分组。如果我想访问我的标签,我只需开始输入 lbl....Visual Studio 会建议我所有的标签,尼克利组合在一起。

然而,在做了越来越多的 Silverlight 和 WPF 工作并利用数据绑定之后,我什至不再命名所有控件,因为我不必从代码隐藏中引用它们(因为实际上不再有任何代码隐藏了) ;)

问题在于混合了标准。

正确的做法是确保每个人都做同样的事情。

int Box = iBottom * nVerticleSide

原始前缀原本用于在方程式中发现问题,但由于您不必去寻找变量声明,因此以某种方式使代码更易于阅读。借助当今的智能编辑器,您可以简单地将任何变量悬停在任何变量上,而不仅仅是对其的缩写,这种类型的匈牙利符号失去了很多含义。

我稍微打破了这个习惯,但是在没有强变量类型的 JavaScript 中,使用类型前缀可能很有用。

使用动态类型语言时,我偶尔会使用 Apps Hungarian。对于静态类型语言,我不这样做。看我的解释 在另一个线程中.

匈牙利表示法在类型安全语言中毫无意义。例如您在旧的 Microsoft 代码中会看到的常见前缀是“lpsz”,意思是“指向以零结尾的字符串的长指针”。自 1700 年代初期以来,我们还没有使用存在短指针和长指针的分段体系结构,C++ 中的正常字符串表示形式始终以零终止,并且编译器是类型安全的,因此不允许我们将非字符串操作应用于细绳。因此,这些信息对程序员来说没有任何实际用处——它只是更多的打字而已。

然而,我使用类似的想法:澄清的前缀 用法 的一个变量。主要有:

  • m = 成员
  • c = 常量
  • s = 静态
  • v = 挥发性
  • p = 指针(pp=指向指针的指针等)
  • i = 索引或迭代器

它们可以组合起来,因此作为指针的静态成员变量将是“mspName”。

这些有什么用呢?

  • 如果用法很重要,最好不断提醒程序员变量是(例如)易失性变量或指针
  • 在我使用 p 前缀之前,指针解引用一直困扰着我。现在很容易知道何时有一个对象 (Orange)、一个指向对象的指针 (pOrange) 或一个指向对象指针 (ppOrange) 的指针。要取消引用一个对象,只需在其名称中的每个 p 前面添加一个星号即可。案件已解决,不再有 deref 错误!
  • 在构造函数中,我通常发现参数名称与成员变量的名称相同(例如尺寸)。我更喜欢使用“ msize = size;”而不是“ size = thesize”或“ this.size = size”。它也更安全:当我想说“mSize = 1”(设置成员)时,我不会意外地使用“size = 1”(设置参数)
  • 在循环中,我的迭代器变量都是有意义的名称。大多数程序员使用“i”或“index”,然后当他们想要内部循环时必须编写新的无意义名称(“j”、“index2”)。我使用带有 i 前缀的有意义的名称(iHospital、iWard、iPatient),因此我始终知道迭代器正在迭代什么。
  • 在循环中,您可以通过使用具有不同前缀的相同基本名称来混合多个相关变量:橙橙 = pOrange[iOrange];这也意味着您不会犯数组索引错误(pApple[i] 看起来不错,但将其写为 pApple[iOrange],错误立即显而易见)。
  • 很多程序员会在不知情的情况下使用我的系统:通过添加像“Index”或“Ptr”这样的长后缀 - 恕我直言,没有任何充分的理由使用比单个字符更长的形式,所以我使用“i”和“p”。更少的打字,更一致,更容易阅读。

这是一个简单的系统,它向代码添加了有意义且有用的信息,并消除了许多简单但常见的编程错误的可能性。

过去 6 个月我一直在 IBM 工作,但我在任何地方都没有看到它(感谢上帝,因为我讨厌它。)我看到的要么是驼峰命名法,要么是 c_style。

thisMethodIsPrettyCool()
this_method_is_pretty_cool()

这取决于您的语言和环境。通常我不会使用它,除非您所处的开发环境使得很难找到变量的类型。

还有两种不同类型的匈牙利表示法。参见乔尔的文章。我找不到它(他的名字并不容易找到),有人有我所说的链接吗?

编辑:韦奇在他的帖子中有我所说的文章。

原始形式(正确的匈牙利表示法:)),其中前缀表示类型(即。变量存储的值的长度、数量是可以的,但并非在所有类型的应用程序中都是必需的。

前缀表示类型(String、int)的流行形式(错误的匈牙利表示法)在大多数现代编程语言中都是无用的。

尤其是像 strA 这样毫无意义的名字。我无法理解我们人们使用带有长前缀的无意义名称,这没有给出任何信息。

我对组件(例如 editFirstName、lblStatus 等)使用基于类型(Systems HN),因为它使自动完成工作更好。

我有时将 App HN 用于类型信息充足的变量。即fpX表示固定指向变量(int类型,但不能与int混合匹配),rawInput表示尚未验证的用户字符串等

作为一名 PHP 程序员,它的类型非常松散,我不打算使用它。然而,我偶尔会根据系统的大小和变量的范围将某些东西识别为数组或对象。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top