【发布时间】:2023-03-06 08:19:01
【问题描述】:
是否值得学习该约定,或者它是否会损害可读性和可维护性?
【问题讨论】:
标签: conventions hungarian-notation self-documenting-code
是否值得学习该约定,或者它是否会损害可读性和可维护性?
【问题讨论】:
标签: conventions hungarian-notation self-documenting-code
考虑到大多数使用 Hungarian Notation 的人都在遵循被误解的版本,我会说这毫无意义。
如果你想使用它的原始定义,它可能更有意义,但除此之外它主要是语法糖。
如果您阅读有关该主题的 Wikipedia article,您会发现两个相互冲突的符号,Systems Hungarian Notation 和 Apps Hungarian Notation。
原始的、良好的定义是Apps Hungarian Notation,但大多数人使用Systems Hungarian Notation。
作为这两者的一个例子,考虑用 l 表示长度、a 表示面积和 v 表示体积的前缀。
有了这样的符号,下面的表达式就有意义了:
int vBox = aBottom * lVerticalSide;
但这不是:
int aBottom = lSide1;
如果您要混合前缀,它们将被视为等式的一部分,并且体积 = 面积 * 长度对于盒子来说很好,但是将长度值复制到面积变量中应该会引发一些危险信号。
不幸的是,另一种表示法不太有用,人们在变量名称前加上值的类型,如下所示:
int iLength;
int iVolume;
int iArea;
有些人用 n 表示数字,或 i 表示整数,f 表示浮点数,s 表示字符串等。
最初的前缀是用来发现方程中的问题,但不知何故演变为使代码更易于阅读,因为您不必去寻找变量声明。对于今天的智能编辑器,您只需将鼠标悬停在任何变量上即可找到完整类型,而不仅仅是它的缩写,这种类型的匈牙利符号已经失去了很多意义。
但是,您应该自己决定。我只能说我两个都不用。
编辑 只是添加一个简短的提示,虽然我不使用 Hungarian Notation,但我确实使用了前缀,它是下划线。我在类的所有私有字段前面加上一个 _,否则拼写它们的名称,就像我拼写一个属性一样,标题首字母大写。
【讨论】:
typedef volume_t int; typedef area_t int; typedef length_t int;
作为一个 PHP 程序员,它的类型非常松散,我不打算使用它。但是我偶尔会根据系统的大小和变量的范围将某些东西识别为数组或对象。
【讨论】:
匈牙利符号在类型安全语言中毫无意义。例如您将在旧 Microsoft 代码中看到的常见前缀是“lpsz”,意思是“指向零终止字符串的长指针”。自 1700 年代早期以来,我们还没有使用存在短指针和长指针的分段架构,C++ 中的正常字符串表示总是以零结尾,并且编译器是类型安全的,因此不会让我们将非字符串操作应用于细绳。因此,这些信息对程序员都没有任何实际用处——只是需要更多的输入。
不过,我使用了一个类似的想法:明确变量的用法的前缀。 主要有:
这些可以组合,因此作为指针的静态成员变量将是“mspName”。
这些在哪里有用?
这是一个简单的系统,它为代码添加了有意义和有用的信息,并消除了许多简单但常见的编程错误的可能性。
【讨论】:
我不使用非常严格意义上的匈牙利符号,但我发现自己使用它时会保留一些常见的自定义对象以帮助识别它们,而且我倾向于在 gui 控件对象前面加上它们所使用的控件类型是。例如,labelFirstName、textFirstName 和 buttonSubmit。
【讨论】:
现在范围不是比类型更重要吗,例如
使用重构旧代码的现代技术,搜索和替换符号因为你改变了它的类型是乏味的,编译器会捕捉到类型变化,但通常不会捕捉到范围的不正确使用,明智的命名约定在这里有所帮助。
【讨论】:
我认为匈牙利符号是一种规避我们短期记忆容量的方法。根据心理学家的说法,我们可以存储大约 7 plus-or-minus 2 chunks 的信息。通过包含前缀添加的额外信息可以帮助我们提供有关标识符含义的更多详细信息,即使没有其他上下文也是如此。换句话说,我们可以猜测变量的用途,而无需查看它是如何使用或声明的。这可以通过应用 encapsulation 和 single responsibility principle 等 oo 技术来避免。
我不知道这是否经过实证研究。我假设当我们尝试理解具有超过 9 个实例变量的类或具有超过 9 个局部变量的方法时,工作量会显着增加。
【讨论】:
我对组件(例如editFirstName、lblStatus 等)使用基于类型的(系统HN),因为它使自动完成功能更好。
我有时将 App HN 用于类型信息不足的变量。即 fpX 表示一个固定的指向变量(int 类型,但不能与一个 int 混合匹配),rawInput 表示尚未验证的用户字符串等
【讨论】:
当我看到匈牙利语的讨论时,我很高兴看到人们努力思考如何使他们的代码更清晰,以及如何让错误更明显。这正是我们应该做的!
但不要忘记,除了命名之外,您还可以使用一些强大的工具。
提取方法如果您的方法变得太长以至于您的变量声明已经滚动到屏幕顶部,请考虑使您的方法更小。 (如果你的方法太多,考虑一个新的类。)
强类型如果您发现您将邮政编码存储在一个整数变量中并将它们分配给一个鞋码整数变量,考虑为邮政编码和鞋码分类。然后您的错误将在编译时被捕获,而不需要人工仔细检查。当我这样做时,我通常会在我的代码中找到一堆特定于邮政编码和鞋码的逻辑,然后我可以将它们转移到我的新课程中。突然间,我的所有代码都变得更清晰、更简单,并且不受某些类型的错误的影响。哇。
总结一下:是的,请认真思考如何在代码中使用名称来清楚地表达您的想法,但也要看看您可以调用的其他强大的 OO 工具。
【讨论】:
在使用动态类型语言时,我偶尔会使用 Apps Hungarian。对于静态类型的语言,我没有。看我的解释in the other thread。
【讨论】:
原始形式(正确的匈牙利表示法:)),其中前缀表示变量存储的值的类型(即长度、数量)是可以的,但并非在所有类型的应用程序中都是必需的。
在大多数现代编程语言中,前缀表示类型 (String, int) 的流行形式(The Wrong Hungarian Notation)是无用的。
尤其是像 strA 这样无意义的名字。我无法理解我们人们使用带有长前缀的无意义名称。
【讨论】:
原来的前缀是 用于发现方程中的问题, 但不知何故演变为制作 代码更容易阅读,因为 你不必去寻找 变量声明。与今天 智能编辑器,您可以轻松地 将鼠标悬停在任何变量上以查找 完整的类型,而不仅仅是一个 它的缩写,这种类型的 匈牙利符号丢失了很多 它的含义。
我稍微改掉了这个习惯,但是在没有强变量类型的 JavaScript 中使用类型前缀可能很有用。
【讨论】:
问题在于混合标准。
正确的做法是确保每个人都做同样的事情。
int Box = iBottom * nVerticleSide
【讨论】:
很抱歉跟进一个问题,但前缀接口“I”是否符合匈牙利表示法?如果是这样的话,那么是的,很多人在现实世界中使用它。如果没有,请忽略它。
【讨论】:
我为按钮、文本框和标签等 UI 元素使用匈牙利命名法。主要好处是在 Visual Studio Intellisense 弹出窗口中进行分组。如果我想访问我的标签,我只需开始输入 lbl....,Visual Studio 就会建议我所有的标签,nicley 组合在一起。
但是,在利用数据绑定做了越来越多 Silverlight 和 WPF 的东西之后,我什至不再命名我的所有控件,因为我不必从代码隐藏中引用它们(因为真的没有任何代码隐藏了;)
【讨论】:
当涉及到 UI 元素时,我仍然使用匈牙利表示法,其中几个 UI 元素与特定对象/值相关,例如,
lblFirstName 为标签对象,txtFirstName 为文本框。我绝对不能将它们都命名为“FirstName”,即使 那 是两个对象的关注/责任。
其他人如何命名 UI 元素?
【讨论】:
这取决于您的语言和环境。通常我不会使用它,除非您所处的开发环境很难找到变量的类型。
还有两种不同类型的匈牙利符号。参见乔尔的文章。我找不到(他的名字不太容易找到),有人有我指的那个的链接吗?
编辑:Wedge 在他的帖子中有我的意思。
【讨论】:
如果使用得当,匈牙利命名约定会很有用,但不幸的是,它往往被误用的频率更高。
阅读 Joel Spolsky 的文章 Making Wrong Code Look Wrong 了解适当的观点和理由。
本质上,基于类型的匈牙利表示法,其中变量以有关其类型的信息为前缀(例如,对象是否是字符串、句柄、int 等)大多是无用的,通常只会增加开销而几乎没有好处。遗憾的是,这是大多数人都熟悉的匈牙利符号。然而,所设想的匈牙利符号的意图是添加关于变量包含的数据“种类”的信息。这允许您将不应该被允许混合在一起的其他类型的数据划分类型的数据,除非可能通过一些转换过程。例如,基于像素的坐标与其他单位的坐标,或不安全的用户输入与来自安全来源的数据等。
这样看,如果您发现自己通过代码来查找有关变量的信息,那么您可能需要调整命名方案以包含该信息,这就是匈牙利约定的精髓。
请注意,匈牙利表示法的替代方法是使用更多类来显示变量使用的意图,而不是到处依赖原始类型。例如,您可以为不安全的用户输入使用简单的字符串包装器类,并为安全数据使用单独的包装器类,而不是为不安全的用户输入使用变量前缀。在强类型语言中,这具有由编译器强制执行分区的优势(即使在弱类型语言中,您通常也可以添加自己的tripwire代码),但增加的开销并非微不足道。
【讨论】:
我认为匈牙利符号是通往更易读代码的“路径”上的一个有趣的脚注,如果做得好,比不做更好。
尽管如此,我宁愿取消它,而不是这样:
int vBox = aBottom * lVerticalSide;
写这个:
int boxVolume = bottomArea * verticalHeight;
现在是 2008 年。我们不再有 80 个字符的固定宽度屏幕了!
此外,如果您编写的变量名比这长得多,那么无论如何您都应该考虑重构为对象或函数。
【讨论】:
它毫无意义(而且会分散注意力),但在我的公司中使用率相对较高,至少对于整数、字符串、布尔值和双精度数等类型而言。
sValue、iCount、dAmount 或 fAmount 和 bFlag 之类的东西无处不在。
曾几何时,这种约定是有充分理由的。现在,它是一种癌症。
【讨论】:
过去 6 个月我一直在 IBM 工作,但我在任何地方都没有见过它(感谢上帝,因为我讨厌它。)我看到了 camelCase 或 c_style。
thisMethodIsPrettyCool()
this_method_is_pretty_cool()
【讨论】: