是否有用于命名类型的良好技术或测试?


23

一个尴尬,开放的问题,但这是我一直碰到的问题:

易于维护和使用的软件是经过精心设计的软件。试图使设计更直观意味着对组件进行命名,以使下一个开发人员应该能够推断出组件的功能。这就是为什么我们不将类命名为“ Type1”,“ Type2”等的原因。

当您对现实世界的概念(例如客户)进行建模时,这通常就像在对现实世界的概念进行建模后命名类型一样简单。但是,当您构建面向系统的抽象事物时,很容易用尽易于理解和消化的名称。

当尝试使用基本类型或接口描述组件的类型(而不是它们的工作方式)来命名类型系列时,对我来说,情况变得更糟。这自然导致每种派生类型试图描述实现的风格(例如IDataConnectionSqlConnection在.NET Framework中),但是如何表达复杂的内容,例如“通过反射工作并寻找一组特定的属性”呢?

然后,当你终于选择了一个名字,你觉得类型描述什么它试图做,你的同事问:“跆拳道这是否DomainSecurityMetadataProvider实际上做什么?

是否有任何好的技术来为组件选择一个好记的名称,或者如何在不弄乱名称的情况下构建一组组件?

我可以对名称进行任何简单的测试,以更好地了解名称是否为“好”,并且对其他人应该更直观吗?


20
六种证明对我有用的技术:1)花很多时间发明名称2)使用代码审查3)毫不犹豫地重命名4)花很多时间发明名称5)使用代码审查6)不要犹豫,改名
2012年

5
@gnat:请发布您的答案作为答案,以便我们投票赞成。
S.Lott,2012年


3
在进行新开发时,我经常使用同义词库来帮助我拿出好名字。
Wily博士的学徒

3
我尽量避免将任何东西称为“经理”。艾伦·格林Alan Green)杰夫·阿特伍德Jeff Atwood)辩称,该术语使用过度,过于含糊,无法传达含义。我必须同意。
Wily博士的学徒

Answers:


41

对于命名,有六种经证明对我有用的技术

  1. 花很多时间发明名字
  2. 使用代码审查
  3. 不要犹豫,重命名
  4. 花很多时间发明名字
  5. 使用代码审查
  6. 不要犹豫,重命名

PS。如果您的API即将公开,则在此之前适用-因为,您知道,

“像钻石一样,公共API永远存在。您有机会把它弄对,所以请尽力而为...”(Joshua Bloch,《如何设计一个好的API及其重要性》


1
如果是公共API,则可以使用三种其他技术...
UncleZeiv 2012年

1
@UncleZeiv:如...?
FrustratedWithFormsDesigner 2012年

3
@FrustratedWithFormsDesigner:1,花费了大量的时间发明了名称2.使用代码审查和3。不要犹豫,重命名
美国洛特

3
这个答案使我确信:通常,没有简单的方法来正确命名。只有努力工作。
Paul Turner 2012年

4
7.如果事实证明不可能为它们设计一个合适的名称,请不要犹豫重新设计类型或函数。设计良好的代码始终可以正确命名。
Joren 2012年

8

我的基本测试是,是否可以仅使用变量中的单词来描述变量的功能:

例如,如果DomainSecurityMetadataProvider“提供域安全性元数据”或“提供与域安全性有关的元数据”,那就很好。

但是,有些细微差别因人而异:

例如,对我来说,original_team_code是原始团队的代码,而对于其他人,它可能是原始团队的代码。我个人最喜欢的一个是“ UnsafeLegacyMutex”,我忍不住读为“这是不安全的旧版互斥对象”,而不是“这是ThreadUnsafe旧版代码的互斥体”。

因此,我的扩展测试是将变量写在板子/ Wiki /聊天中,让人们猜测它的含义。


7

是否有任何好的技术来为组件选择一个好记的名称,或者如何在不弄乱名称的情况下构建一组组件?

并不是的。

但是,一个技巧是避免“被动语态”。

“ DomainSecurityMetadataProvider”是被动的。没有动词,所有名词和名词都用作形容词。

“ ProvideMetadataForDomainSecurity”更为活跃。有一个动词。

面向对象编程是所有(真的)名词-动词。名词==对象。动词==方法。因此,类名通常非常“有害”。打破这种习惯并开始插入动词是困难的。

我可以对名称进行任何简单的测试,以更好地了解名称是否为“好”,并且对其他人应该更直观吗?

是。您在问题中定义了出色的测试。问别人。

在过去,我们将其称为“设计演练”。在瀑布方法中,这是一件大事,出汗了。如今,使用敏捷方法,应该是类的作者和用户之间的普通协作。它不会(也不应该)花费很长时间。在编写测试(和代码)之前讨论设计(和名称)将减少令人惊讶的因素,并可以防止WTF。


12
不确定我是否同意被动语态的想法。对我来说,课堂更像名词。
deworde 2012年

7
一般来说,我试图将类型名称保留为被动语态,因为它适合OOP的名词-动词风格。我会认为ProvideMetadataForDomainSecurity这是一个不好的类型名称。方法名称通常更容易精确地命名,因为我可以随意使用动词。语言的限制是问题的症结所在。
保罗·特纳

尽管我喜欢“问人”作为一项真正的考验,但我必须询问同事每天至少两次命名。我希望有一些不需要别人花费时间的东西。
保罗·特纳

2
类作为名词确实有意义。问题是这些复杂的类带有很长的名词形容词短语。介词也可能有帮助。
S.Lott

2
协作是好的软件的秘密。合作需要时间。好的写作没有皇家之路。
S.Lott 2012年

6

使用词库

在进行新开发时,通常会参考一个词库,以便找到合适的词来描述我的类和方法。

主要包含操作逻辑的类

我倾向于命名主要在名词-动词结构中提供操作方法的类,例如“ EntityProvider”,“ EntityLocator”等。

这些类通常不包含很多状态。

包含状态的类

UI屏幕和数据实体通常是有状态的,因此我仅用名词或形容词-名词模式来命名这些类。

示例:人员,员工,现任员工,前员工

实用程序类

仅包含静态方法的类通常被视为“实用程序”类,因此我始终使用“实用程序”后缀来命名它们。

示例:网络实用程序,文件实用程序

测验

我没有任何好的测试来确定某事物的名称是否错误,但是我建议尝试使用名称中的单个名词和/或单个动词,然后考虑该名词/动词是否准确地描述了您的名字重新命名。

如果您认为该名称未捕获到类/方法中的更多内容,则可能需要重构该类/方法。

艾伦·格林Alan Green)杰夫·阿特伍德Jeff Attwood)曾写过用“ Manager”后缀命名类的弊端。他们认为,“经理”一词已被过度使用且过于模糊,无法传达任何有意义的信息。我必须同意。

Jeff的文章还提供了Steve McConnell的Code Complete中的建议准则列表。

变数

最近,我一直在尝试使用包含介词的较长描述性变量/参数名称,例如“ Of”,“ By”,“ For”等。下面显示了一些示例:

string firstNameOfEmployee;

string lastNameOfEmployee;

// here I nimbly avoid worrying about whether to call it "Id" or "ID" :)
int idOfEmployee;

decimal amountForDeposit;

Account accountForDeposit;

我发现这与Visual Studio的intellisense功能配合得很好,从而使键入这些长名称变得容易。我还发现,变量名前缀(例如personID,personFirstName,personLastName与idOfPerson,firstNameOfPerson,lastNameOfPerson)的重复较少,从而提供了更好的“哈希”,从而使intellisense更加有用。


1
我将继续讲长的变量名,Visual Studio(如果您正在使用它)使这毫无疑问。拥有明确的长变量名要比短变量名(您必须“思考”或研究该名的实际含义)的危害要小得多。还考虑上下文。我宁愿看到“ peopleToDelete”而不是“ listOfPeople”。同样,Visual Studio会告诉您变量的类型,无需包含它。
约翰·布布里斯基

我还不喜欢您添加到变量名中的详尽的匈牙利符号。我不需要关心人员ID的集合是List,数组IEnumerable还是ConcurrentQueue。我需要枚举大量的ID,并且如何存储它们的实现细节是不必要的麻烦。尽管我通常都同意,如果长名称的描述性强得多,则应优先使用短名称而不是清楚的名称。
Allon Guralnek 2012年

@Allon-有趣的是,我将根据SkippyFire的评论修改答案。我实际上同意你的看法;我的示例带有匈牙利符号。我唯一的防御是在没有可用的IDE的情况下,很容易阅读代码并理解所涉及的数据类型,例如,如果我正在阅读源代码控制差异。不过,那不是借口。:)我要修改我的例子是沿着firstNameOfEmployee,lastNameOfEmployee等的线
威利博士的学徒

2

然后,当您最终为要描述的类型选择了一个名称时,您的同事会问:“ WTF这个DomainSecurityMetadataProvider实际上是做什么的?”

您希望为复杂且针对特定领域的课程使用哪种名称?这几乎与不使班级名称成为句子(将使每个人都认为您对单个班级负有太多责任)的结果一样好。

我会考虑从名称中删除提供者。如果它特别提到元数据,那么每个人都已经知道您正在使用反射。您可以使它一个词更简洁(或者可以更改为另一个词-它比起您撰写的内容,更像是消费者而不是提供者)


有问题的元数据不是从反射派生的(但它确实描述了如何处理类型)。该类型实现一个ISecurityMetadataProvider接口,该接口在安全基础结构中存在一个可注入点,以向子系统提供信息。命名很难。
保罗·特纳

我认为DomainSecurityMetadataProviderDomainSecurityMetadata对象的提供者,DomainSecurityMetadata元数据本身就在哪里。清晰易懂的名称。我什至不需要知道是什么DomainSecurityMetadata!它只是此提供程序提供的某些对象。仅仅删除一个Provider后缀并不能提高可读性,但是恰恰相反-减少它。没有这个后缀,我认为这只是一些元数据(某些元数据的容器对象),而不是从(提供者)获取元数据的对象。
Ruslan Stelmachenko '18

0

使用隐喻来描述系统的各个部分。它不仅使您发现新的类比,而且将有助于更轻松地命名。

(我知道这不是一个很好的例子,但是无论如何)例如,您可以将变量或类型称为mailbox,将其用作接收类消息的队列。


-1

我会非常坚定的一件事是,绝对不允许名称不正确。最好的例子是,在进行一些重构期间,更改了许多代码,并且一些变量开始引用其名称所暗示的内容以外的内容。

很快,一个程序员花了很多年的时间并使用一些非常昂贵的数据库调用来试图获取某些已经提取并存储的数据。我将所有内容重命名,然后突然我们可以删除大量过于复杂和错误的逻辑。


1
您应该删除此答案,然后将其编辑为原始答案
Ryathal 2012年

我认为这是其他答案不同的答案。
deworde 2012年

-1

希望您很少考虑名称的情况很少。当出现这些情况时,只需编写一段说明该类的功能。与功能中注释或功能级别注释相反,类的主要目的很少更改,因此注释过时的风险相对较小。因此,您可以编写几个段落,甚至可以绘制ASCII来解释类的作用,这是一种奢侈的方式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.