Java方法名称何时过长?[关闭]


173

在过去的几周里,我见过有些人在方法或类上使用非常长的名称(50个字符),这通常是在提高可读性的前提下进行的,我认为这样的长名称可以表明我们如果需要这么长的名称,尝试在方法类中做很多事情或做太多事情,但是我想知道你们对此有何看法。

一个例子是:

getNumberOfSkinCareEligibleItemsWithinTransaction

19
是的,这是“代码异味” ... c2.com/cgi/wiki?LongMethodSmell
Dan Rosenstark 2010年

23
如果长度大于666个字符,则说明您遇到了问题。
Thomas Eding

8
@yar在您的示例中,“长方法”的反面是“短方法”,这被认为是一件好事。因此,显然不是在引用方法名称。它指的是代码行(或类似的东西)。例如,这f()是一个非常短的函数,但是它当然不是一个好习惯……您应该告诉一些编程数学家:)
sfussenegger 2010年

3
@sfussenegger,是的。但是我押注在方法名长度和方法长度之间的相关性。f()可能不是一个很好的功能,但是那个$()家伙就像Javascript方法世界中的摇滚明星一样。
Dan Rosenstark'2

7
@yar,您给出的链接以行为单位引用了方法的长度,而不是方法名称的长度。
托尔比约恩Ravn的安德森

Answers:


397

如果存在较短的名称(可以平等地传达方法的行为),则Java或任何其他语言的名称都太长。


65
数学上优雅。
Ricket 2010年

301
因此,例如,boolean doesShorterNameExistThatEquallyConvaysTheBehaviorOfTheMethod(String s)应将其重构为boolean isTooLong(String s)
2010年

6
我不太同意,因为您不仅要传达行为,而且要保持项目和语言的惯例。因此,在Python中您可能会说,eligible_items_cnt但在Java中您通常会说getEligibleItemsCount
flybywire 2010年

17
@flybywire:任何使您写过长名称的约定都是可疑的。
MAK 2010年

20
@MAK @美国洛特什么getLength()length()?我真的很喜欢在输入“ get”或“ set”后查看自动填充-因此在这种情况下,我更喜欢对流而不是简洁。
sfussenegger 2010年

202

减少方法名称长度的一些技术:

  1. 如果您的整个程序,课程或模块是关于“皮肤护理项目”的,则可以放弃皮肤护理。例如,如果您的班级名为,则将您SkinCareUtils带到getNumberOfEligibleItemsWithinTransaction

  2. 您可以更改为,getNumberOfEligibleItemsInTransaction

  3. 您可以将Transaction更改为Tx,从而可以转到getNumberOfEligibleItemsInTx

  4. 或者,如果该方法接受类型的参数,则Transaction可以完全删除InTx:getNumberOfEligibleItems

  5. 您通过计数更改numberOf: getEligibleItemsCount

现在,这是非常合理的。而且缩短了60%。


11
此外,5)将投入getEligibleItems()getEligibleItemsCount()按字母顺序排序的列表彼此相邻(如自动完成或javadoc中)
sfussenegger

4
通常来说,简称是符合name句规则的。
sal 2010年

2
@mercator在getEligibleItems上使用诸如getEligibleItems之类的标准约定可以减少语句中出现歧义的可能性。该方法应该做什么的模棱两可增加了可读性。如果不进一步研究该方法,那么从长远来看,“计数”的方法要比“获取”的方法所完成的不清楚。
条例草案

53
我不喜欢像简称TxCntgrph,等...(顺便说一句,Tx是短期的“传送”或“发射器”)
Meinersbur

14
是的,在您决定使用“ Tx”之前,我同意您的意见。
Ponkadoodle

183

只是为了更改,一个非主观的答案:65536个字符。

A.java:1:字符串“ xxxxxxxxxxxxxxxxxxxxx ...”的UTF8表示对于常量池来说太长了

;-)


4
是的,当JVM无法处理它时,它的时间太长了:)
Anurag 2010年

35
+1 字面解释。
sal 2010年

37
从技术上讲,Java语言规范没有标识符长度的上限。这是您的JVM实现的限制。干杯!
uckelman 2010年

13
Sun的编译器显然不符合规范。java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8说:“标识符是无限长度的序列...”
Michael Myers

6
错误消息指出,JVM规范确实有上限。utf8的常量池表示形式限于此处指定的 2 ^ 16字节。类名和方法名必须作为utf8存储在常量池中。
thejoshwolfe 2011年

42

我同意所有人的观点:方法名称不应太长。我确实想添加一个例外:

但是,JUnit测试方法的名称可能很长,应该类似于句子。

为什么?

  • 因为在其他代码中未调用它们。
  • 因为它们被用作测试名称。
  • 因为它们然后可以写成描述需求的句子。(例如,使用AgileDox

例:

    @Test
    public void testDialogClosesDownWhenTheRedButtonIsPressedTwice() {
        ...
    }

有关此想法的更多信息,请参见“ 行为驱动设计 ”。


5
+1我同意它,这也是我正在做的事情,尽管不再需要JUnit 4方法开始test,但这也打开了使用的可能性should:如dialogShouldCloseWhenTheRedButtonIsPressedTwice()。或者,您可以先调用测试类DialogShould,然后再调用方法closeWhenTheRedButtonIsPressedTwice(),以便一起阅读它们:DialogShould.closeWhenTheRedButtonIsPressedTwice()
stivlo

虽然我同意,但我也建议句子太长可能表明测试做得太多!
布赖恩·阿格纽

17

上下文“ ... WithinTransaction”应该很明显。这就是面向对象的全部意义。

该方法是类的一部分。如果该类不是“ Transaction”的意思,并且它不能使您不必一直说“ WithinTransaction”,那么您就会遇到问题。


2
也可以采用某种交易参数
willcodejavaforfood 2010年

3
从上面得分最高的答案可以看出,寻求内陆简化而不是面向对象的建议。+1
Dan Rosenstark

@yar人们永远不会错。
CurtainDog 2010年

12

我倾向于使用haiku规则来命名:

 Seven syllable class names 
 five for variables
 seven for method and other names

这些是最大名称的经验法则。我只有在提高可读性时才违反此规定。诸如recalculateMortgageInterest(currentRate,quoteSet ...)之类的东西比recalculateMortgageInterestRate或recalculateMortgageInterestRateFromSet更好,因为它涉及费率和一组引号的事实从嵌入式文档(如javadoc或.NET等效文档)中应该很清楚。

注意:不是真正的句,因为它是7-5-7而不是5-7-5。但是我仍然更喜欢将其称为haiku。


13
班级分为7个,变量少于5个,其余7个
詹姆斯

8
“变量最多为五个”(少于五个是不准确的)
Jason S 2010年

较小的名称可能导致较低的代码可读性。
Deniss M.

10

Java具有鼓励长名的文化,这可能是因为IDE具有良好的自动补全功能。

这个站点说JRE中最长的类名InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState是92个字符长。

至于最长的方法名称,我找到了这个supportsDataDefinitionAndDataManipulationTransactions,它是52个字符。


20
看起来该类是由Redundancy Department雇用的命名人员命名的,以在Redundancy Department命名事物。
Michael Madsen

1
@MichaelMadsen:真的多余吗,还是描述嵌套在另一个框架中的框架?
endolith 2012年

PEP-8想要一个带有该类名称的单词。
Mateen Ulhaq

9

如果小字句会用的话,切勿使用长字。

我认为您的“方法名称的长度与方法的长度成正比”的论点并没有真正成立。

以您提供的示例为例:“ getNumberOfSkinCareEligibleItemsWithinTransaction”。在我看来,这听起来像是一件事:它计算属于某个类别的交易中的项目数。当然,我不能不看该方法的实际代码就做出判断,但这听起来对我来说是一个好方法。

另一方面,我看到了很多方法的名称非常简短,这些名称可以做很多工作,例如“ processSale”或流行的“ doStuff”。

我认为很难对方法名称的长度给出严格的规定,但目标应该是:足够长以传达函数的作用,足够短以使可读。在此示例中,我认为“ getSkinCareCount”可能就足够了。问题是您需要区分什么。如果您有一个功能可以计算交易中符合皮肤护理项目的功能,而另一个功能可以计算其他事物中符合皮肤护理项目的功能,那么“ withinTransactions”会增加价值。但是,如果在交易之外谈论这些项目并不意味着什么,那么用这些多余的信息来弄乱名字就毫无意义。

第二,我认为假设任何可管理长度的名称都能告诉您该函数在除最琐碎的情况以外的所有情况中的确切功能是不现实的。一个现实的目标是创建一个给读者一个线索的名称,并在以后记住该名称。就像,如果我试图找到计算达到扭曲速度需要消耗多少反物质的代码,如果我查看函数名称并看到“ calibrateTransporter”,“ firePhasers”和“ calcAntimatterBurn”,那么很明显前两个不是,但第三个可能是。如果我检查发现确实是我要寻找的那个,那么很容易记住,当我明天回来为这个问题做更多工作时。够了

三个相似的长名称比短名称更容易混淆。如果我有两个名为“ calcSalesmanPay”和“ calcGeekPay”的函数,那么我可以快速猜出哪个函数。但是,如果将它们分别称为“ calculateMonthlyCheckAmountForSalesmanForExportToAccountingSystemAndReconciliation”和“ calculateMonthlyCheckAmountForProgrammersForExportToAccountingSystemAndReconciliation”,则我必须研究这些名称以了解哪个是哪个。在这种情况下,名称中的额外信息可能适得其反。它将半秒钟的思考变为30秒钟的思考。


对于遭受的这个错误答案,+ 1。
Dan Rosenstark 2010年

7

按照您希望的方式设计界面,并使实现匹配。

例如,也许我会写成

getTransaction().getItems(SKIN_CARE).getEligible().size()

或使用Java 8流:

getTransaction().getItems().stream()
    .filter(item -> item.getType() == SKIN_CARE)
    .filter(item -> item.isEligible())
    .count();

6

我的规则如下:如果名称太长以至于必须以自己的名字出现,那么名称就太长了。(实际上,这意味着我很少超过20个字符。)

这是基于研究表明,可见的垂直代码行数与编码速度/有效性呈正相关。如果类/方法名称开始严重损害这一点,则它们太长了。

在声明方法/类的位置添加注释,如果您想对其进行详细说明,请让IDE带您到那里。


我喜欢这样的规则。只要记住您/您的团队是随机组成的,那一切就很好。另一方面,我不能对此表示反对,因为“研究显示”实际上需要与该研究有关的链接,或其他有关的东西……
Dan Rosenstark 2010年

5

方法本身的长度可能更好地指示了它是否做得太多,即使这样也只能给您一个大概的想法。您应该为简洁而努力,但描述性更重要。如果您不能用较短的名称传达相同的含义,则名称本身可能还可以。


3

下次要写方法名称时,请考虑一下波纹管引号

"The man who is going to maintain your code is a phyco who knows where you stay"

13
好东西他只是海藻,而不是“心理”
StingyJack 2010年

2

该方法名称肯定太长。当我阅读如此大小的方法名称时,我的想法往往会徘徊。就像读一个没有空格的句子。

就我个人而言,我希望方法中的单词尽可能少。如果包和类名可以传达含义,则将为您提供帮助。如果该类的职责非常简洁,则无需使用巨大的方法名称。我很好奇为什么“ WithinTransaction”在那里。

“ getNumberOfSkinCareEligibleItemsWithinTransaction”可能变为:

com.mycompany.app.product.SkinCareQuery.getNumEligibleItems();

然后,在使用时,该方法可能看起来像“ query.getNumEligibleItems()”


2

如果较短的名称将使整个程序或程序的重要部分具有更好的代码可读性,则变量名太长。

如果使用更长的名称,则可以传达有关值的更多信息。但是,如果名称太长,则会使代码混乱,并降低理解其余代码的能力。这通常是通过引起换行并将其他代码行推离页面而发生的。

诀窍是确定哪种将提供更好的可读性。如果该变量经常或在较短的空间中多次使用,则最好给它起一个短名称并使用注释来说明。读者可以轻松参考该评论。如果在整个程序中经常使用该变量,通常将其用作参数或在其他复杂的操作中使用,则最好精简名称或使用缩写词来提醒读者。如果忘记了含义,他们总是可以通过变量声明引用注释。

这并非易事,因为您必须考虑代码阅读器可能试图理解的内容,并且还要考虑代码随着时间的变化和增长的方式。这就是为什么很难命名的原因。

可读性是为什么可以将i用作循环计数器而不是DescriptiveLoopCounterName的原因。因为这是变量的最常用用法,所以您可以花费最少的屏幕空间来解释其存在的原因。较长的名称只会使您更难理解测试循环条件或索引数组的方式,从而浪费时间。

另一方面,如果像复杂操作中那样很少使用函数或变量(例如传递给多参数函数调用),则可以给它起一个过分描述性的名称。


1

与任何其他语言一样:当它不再描述该功能执行的单个动作时。


1

我会说结合好答案并做到合理。

完整,清晰,可读地描述该方法的作用。

如果方法名称似乎太长,请重构该方法以减少操作。


1

当方法的名称换行到另一行并且对该方法的调用是该行上唯一的事情并且开始时非常接近边距时,太长了。您必须考虑将要使用该屏幕的人的平均屏幕尺寸。

但!如果名称看起来太长,则可能太长。解决该问题的方法是以这样一种方式编写代码,即您位于上下文中,并且名称简短但在其他上下文中重复。这就像您可以用英语说“她”或“他”而不是某人的全名一样。


1

太含蓄地解释事情的实质已经太久了。

例如,这些名称在功能上是等效的。

在Java中: java.sql.SQLIntegrityConstraintViolationException

在Python / Django中: django.db.IntegrityError

问问自己,在SQL / db程序包中,您还能想到多少种类型的完整性错误?;)因此db.IntegrityError就足够了。


您总是可以反其道而行之。当用言语方式解释问题的实质时,很显然该方法还可以做什么,否则可能引起混乱,并可能导致错误使用该方法。
Jonas Geiregat 2014年

0

标识符名称超过Java编译器可以处理的长度时,它太长。


3
什么?!我不明白为什么我为此被否决了。这个问题并没有要求一个必要的条件,只是一个足够的条件!
uckelman 2010年

0

这里有两种方法或观点:一种是方法名称有多长真的无关紧要,只要它能尽可能描述性地描述方法的作用即可(Java最佳实践的基本规则)。另一方面,我同意flybywire的帖子。我们应该利用我们的智慧来尝试尽可能减少方法名称,但又不要减少其描述性。描述性更重要:)


0

名称太长,如果:

  • 花费超过1秒的时间来阅读
  • 占用的RAM比分配给JVM的RAM多
  • 是荒唐的名字吗
  • 如果一个简短的名字很合理
  • 如果它在您的IDE中环绕

老实说,该名称仅需要将其目的传达给将其用作公共API方法的开发人员,或者在您离开时必须维护代码。只记得KISS(保持简单愚蠢)

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.