人们在现实世界中使用匈牙利命名约定吗?

时间:2008-08-07 22:31:14

标签: conventions hungarian-notation self-documenting-code

是否值得学习惯例或者是否可读性和可维护性受到了祸害?

20 个答案:

答案 0 :(得分:57)

考虑到大多数使用匈牙利表示法的人都遵循了误解的版本,我认为这是毫无意义的。

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

如果您阅读了有关主题的Wikipedia article,您会发现两个相互矛盾的表示法,系统匈牙利表示法 Apps匈牙利表示法

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

作为两者的一个例子,考虑使用l表示长度的前缀,a表示区域,v表示音量。

使用这种表示法,以下表达式是有意义的:

int vBox = aBottom * lVerticalSide;

但这不是:

int aBottom = lSide1;

如果你混合前缀,它们将被视为等式的一部分,而volume = area * length对于一个盒子来说很好,但是将长度值复制到一个区域变量中会引起一些危险信号。 / p>

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

int iLength;
int iVolume;
int iArea;

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

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

但是,你应该自己决定。我只能说我不使用它们。


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

答案 1 :(得分:21)

匈牙利命名惯例在正确使用时非常有用,不幸的是它往往会被误用。

阅读Joel Spolsky的文章Making Wrong Code Look Wrong,以获得适当的观点和理由。

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

以这种方式看待它,如果您发现自己通过代码查找变量信息,那么您可能需要调整命名方案以包含该信息,这是匈牙利惯例的本质。

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

答案 2 :(得分:14)

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

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

其他人如何处理命名UI元素?

答案 3 :(得分:9)

这是毫无意义的(而且分散注意力),但在我的公司使用相对较多,至少对于像int,字符串,布尔值和双打这样的类型。

sValueiCountdAmountfAmount以及bFlag等无处不在。

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

答案 4 :(得分:9)

我认为匈牙利符号是一条有趣的脚注,沿着“路径”提供更易读的代码,如果做得恰当,最好不要这样做。

虽然说,但我宁愿废除它,而不是这个:

int vBox = aBottom * lVerticalSide;

写下这个:

int boxVolume = bottomArea * verticalHeight;

这是2008年。我们没有80个字符的固定宽度屏幕了!

另外,如果你要编写的变量名远远超过你应该考虑重构为对象或函数的变量名。

答案 5 :(得分:5)

很抱歉跟进一个问题,但前缀接口“I”是否有资格作为匈牙利表示法?如果是这样,那么是的,很多人都在现实世界中使用它。如果没有,请忽略这一点。

答案 6 :(得分:5)

这些天不是范围更重要,例如

  • l for local
  • a for argument
  • m for member
  • g for global

使用现代技术重构旧代码,搜索和替换符号因为你改变了它的类型是繁琐的,编译器会捕获类型更改,但通常不会捕获不正确的范围使用,合理的命名约定在这里有帮助。

答案 7 :(得分:5)

我认为匈牙利乐谱是一种规避短期记忆能力的方法。根据心理学家的说法,我们可以存储大约 7 plus-or-minus 2 chunks 的信息。通过包含前缀添加的额外信息有助于我们提供有关标识符含义的更多详细信息,即使没有其他上下文也是如此。换句话说,我们可以猜测变量是什么,而不会看到它是如何被使用或声明的。这可以通过应用encapsulationsingle responsibility principle等技术来避免。

我不知道这是否已经凭经验研究过。我假设当我们尝试理解具有9个以上实例变量的类或具有9个以上局部变量的方法时,努力量会大大增加。

答案 8 :(得分:4)

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

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

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

强类型如果您发现存储在整数变量中的邮政编码并将其分配给鞋码整数变量,考虑为邮政编码制作一个类,为鞋号制作一个类。然后你的bug将在编译时捕获,而不是需要人工仔细检查。当我这样做时,我通常会发现一堆邮政编码和鞋码特定的逻辑,我已经在我的代码周围填充,然后我可以进入我的新类。突然间,我的所有代码都变得更加清晰,简单,并且免受某些类别的错误的影响。哇。

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

答案 9 :(得分:2)

我没有使用非常严格的匈牙利符号感,但我确实发现自己使用它来节省一些常见的自定义对象以帮助识别它们,而且我倾向于使用控制类型为gui控制对象添加前缀是。例如,labelFirstName,textFirstName和buttonSubmit。

答案 10 :(得分:1)

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

但是,我使用了类似的想法:前缀用于阐明变量的用法。 主要是:

  • m = member
  • c = const
  • s = static
  • v = volatile
  • p =指针(和pp =指向指针的指针等)
  • i = index或iterator

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

这些有用吗?

  • 如果用法很重要,最好不断提醒程序员变量是(例如)volatile或指针
  • 在我使用p前缀之前,指针解除引用一直在进行。现在很容易知道你有一个对象(橙色)指向对象的指针(pOrange)或指向对象指针的指针(ppOrange)。要取消引用对象,只需在其前面为其名称中的每个p添加一个星号。案例解决了,没有更多的反对错误!
  • 在构造函数中,我经常发现参数名称与成员变量的名称(例如大小)相同。我更喜欢使用“mSize = size;”比“size = theSize”或“this.size = size”。它也更安全:当我打算说“mSize = 1”(设置成员)时,我不小心使用“size = 1”(设置参数)
  • 在循环中,我的迭代器变量都是有意义的名称。大多数程序员使用“i”或“index”,然后在需要内循环时必须编写新的无意义名称(“j”,“index2”)。我使用带有i前缀的有意义的名称(iHospital,iWard,iPatient),所以我总是知道迭代器在迭代什么。
  • 在循环中,您可以通过使用具有不同前缀的相同基本名称来混合多个相关变量:Orange orange = pOrange [iOrange];这也意味着你不会产生数组索引错误(pApple [i]看起来没问题,但把它写成pApple [iOrange]并且错误很明显)。
  • 许多程序员将使用我的系统而不知道它:通过添加一个冗长的后缀,如“索引”或“Ptr” - 没有任何充分的理由使用比单个字符恕我直言更长的形式,所以我用“我“和”p“。减少打字,更一致,更容易阅读。

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

答案 11 :(得分:1)

我将匈牙利语命名用于UI元素,如按钮,文本框和标签。主要好处是在Visual Studio Intellisense Popup中进行分组。如果我想访问我的标签,我只需要开始输入lbl ....并且Visual Studio会建议所有我的标签,nicley组合在一起。

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

答案 12 :(得分:1)

混合标准有什么不对。

什么是正确的,确保每个人都做同样的事情。

int Box = iBottom * nVerticleSide

答案 13 :(得分:1)

  

原始前缀应该是   用于发现方程中的问题,   但不知何故已经转变为制作   从那时起,代码稍微容易阅读   你不必去寻找   变量声明。随着今天   聪明的编辑,你可以简单地   将鼠标悬停在任何变量上即可找到   完整的类型,而不仅仅是一个   它的缩写,这种类型的   匈牙利的记谱法已经失去了很多   它的意思。

我打破了一点习惯,但在没有强变量输入的JavaScript中,使用类型前缀可能很有用。

答案 14 :(得分:1)

使用动态类型语言时,我偶尔会使用Apps匈牙利语。对于静态类型语言,我不这样做。请参阅我的解释in the other thread

答案 15 :(得分:0)

作为一个非常松散类型的PHP程序员,我没有指出要使用它。但是,根据系统的大小和变量的范围,我偶尔会将某些内容识别为数组或对象。

答案 16 :(得分:0)

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

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

答案 17 :(得分:0)

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

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

特别是像strA这样毫无意义的名字。我无法理解我们人们使用带有长前缀的毫无意义的名字,这些名字什么都没有。

答案 18 :(得分:0)

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

还有两种不同类型的匈牙利表示法。见Joel的文章。我找不到它(他的名字并不能让他们很容易找到),任何人都有链接到我的意思吗?

编辑:Wedge在他的帖子中有我的意思。

答案 19 :(得分:0)

过去6个月我一直在为IBM工作,我没有在任何地方见过它(感谢上帝因为我讨厌它。)我看到了camelCase或c_style。

thisMethodIsPrettyCool()
this_method_is_pretty_cool()