什么时候 Java 方法名太长了? [关闭]
Posted
技术标签:
【中文标题】什么时候 Java 方法名太长了? [关闭]【英文标题】:When is a Java method name too long? [closed] 【发布时间】:2011-01-14 21:50:50 【问题描述】:在过去的几周里,我看到一些人对方法或类使用很长的名称(50 个字符),这通常是在提高可读性的前提下,我认为像这样的长名称是一个指标如果我们需要这么长的名称,我们正在尝试在方法类中做很多或太多,但是我想知道你们对此有何看法。
一个例子是:
getNumberOfSkinCareEligibleItemsWithinTransaction
【问题讨论】:
是的,这是一种“代码味道”...c2.com/cgi/wiki?LongMethodSmell 当它超过 666 个字符时,你就知道你有问题了。 @yar 在您的示例中,“长方法”的反面是“短方法”,这被认为是一件好事。所以它显然不是指方法名称;它指的是代码行(或类似的东西)。例如,f()
是一个非常短的函数,但这肯定不是一个好习惯……而且你应该告诉一些编程数学家 :)
@sfussenegger,这是真的。但我打赌方法名称长度和方法长度之间的相关性。 f()
可能不是一个很棒的功能,但 $()
那个家伙就像 javascript 方法界的摇滚明星。
@yar,您提供的链接指的是方法的长度(以行为单位),而不是方法的长度 name。
【参考方案1】:
Java 或任何其他语言中的名称太长,如果存在同样传达方法行为的较短名称。
【讨论】:
数学上优雅。 所以例如boolean doesShorterNameExistThatEquallyConvaysTheBehaviorOfTheMethod(String s)
应该重构为boolean isTooLong(String s)
。
我不太同意,因为您不仅要传达行为,还要保持项目和语言的约定。所以在 Python 中你可能会说 eligible_items_cnt
但在 Java 中你通常会说 getEligibleItemsCount
。
@flybywire:任何让你写出过长名字的约定都是可疑的。
@MAK @S.Lott getLength()
和 length()
怎么样?我真的很喜欢在输入“get”或“set”后查看自动补全——所以在这种情况下,我更喜欢简洁而不是简洁。【参考方案2】:
一些减少方法名称长度的技巧:
如果您的整个课程、课程或模块都是关于“护肤品”的,您可以放弃护肤。例如,如果您的班级名为SkinCareUtils
,
这会将您带到getNumberOfEligibleItemsWithinTransaction
你可以将within改为in,getNumberOfEligibleItemsInTransaction
您可以将 Transaction 更改为 Tx,这会将您带到 getNumberOfEligibleItemsInTx
。
或者,如果该方法接受 Transaction
类型的参数,您可以完全删除 InTx:getNumberOfEligibleItems
您按计数更改 numberOf:getEligibleItemsCount
现在这是非常合理的。而且缩短了 60%。
【讨论】:
另外,5) 将getEligibleItems()
和getEligibleItemsCount()
在按字母顺序排列的列表中彼此相邻(例如自动完成或javadoc)
通常情况下,较短的名称符合俳句规则。
@mercator 使用像 getEligibleItems 这样的标准约定而不是 countEligibleItems 可以减少语句中出现歧义的机会。该方法应该做什么的模糊性越少,可读性就越强。如果不进一步研究该方法,从长远来看,“计数”的方法不如“获取”的方法完成的清晰。
我不喜欢 Tx
、Cnt
、grph
等缩写词……(顺便说一句,Tx
是“Transmission”或“Transmitter”的缩写)
是的,我同意你的意见,直到你决定使用“Tx”。【参考方案3】:
只是为了改变,一个非主观的答案:65536个字符。
A.java:1:字符串“xxxxxxxxxxxxxxxxxxxx...”的 UTF8 表示太长 对于常量池
;-)
【讨论】:
是的,当 JVM 无法处理它时,它太长了 :) +1 表示 THE 字面答案。 从技术上讲,Java 语言规范没有标识符长度的上限。这是 JVM 实现的限制。干杯! Sun 的编译器显然不符合规范。 java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 说:“标识符是无限长度的序列……” JVM 规范确实 有一个上限,正如错误消息指出的那样。 utf8 的常量池表示限制为 2^16 字节specified here。类名和方法名必须以 utf8 格式存储在常量池中。【参考方案4】:我同意每个人的观点:方法名称不应该太长。不过,我确实想添加一个例外:
但是,JUnit 测试方法的名称可能很长并且应该类似于句子。
为什么?
因为它们没有在其他代码中调用。 因为它们被用作测试名称。 因为它们可以写成描述需求的句子。 (例如,使用AgileDox)例子:
@Test
public void testDialogClosesDownWhenTheRedButtonIsPressedTwice()
...
有关此想法的更多信息,请参阅“Behavior Driven Design”。
【讨论】:
+1 我同意它,这也是我正在做的,虽然 JUnit 4 方法不再需要以test
开头,但这也打开了使用 should
的可能性:这样作为dialogShouldCloseWhenTheRedButtonIsPressedTwice()
。或者你可以调用测试类DialogShould
然后调用方法closeWhenTheRedButtonIsPressedTwice()
,所以一起阅读它们:DialogShould.closeWhenTheRedButtonIsPressedTwice()
。
虽然我同意,但我也建议太长的句子可能表明测试做得太多!【参考方案5】:
上下文“...WithinTransaction”应该是显而易见的。这就是面向对象的全部意义所在。
方法是类的一部分。如果这个类的意思不是“事务”——如果它不能让你不必一直说“WithinTransaction”,那么你就有问题了。
【讨论】:
也可以采用某种交易参数 您可以从上面得分最高的答案中看出,选择内陆简单而不是 OO 建议。 +1 @yar 人们永远不会错。【参考方案6】:Java 有一种鼓励长名称的文化,这可能是因为 IDE 具有良好的自动补全功能。
This site 表示 JRE 中最长的类名是 InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
,长度为 92 个字符。
至于最长的方法名我找到了supportsDataDefinitionAndDataManipulationTransactions
,它是52个字符。
【讨论】:
看起来那个班级是由冗余部门聘请的命名人员在冗余部门命名的。 @MichaelMadsen:真的是多余的,还是描述嵌套在另一个框架中的框架? PEP-8 想要一个具有该类名的单词。 这太搞笑了【参考方案7】:我倾向于使用俳句规则来命名:
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。但我还是更喜欢叫它俳句。
【讨论】:
类获得七个,变量小于五个,其余为七个 “变量最多五个”(小于五个不准确) 较小的名称可能导致较低的代码可读性。【参考方案8】:当一个小字可以使用时,切勿使用长字。
我不认为你的“方法名称的长度与方法的长度成正比”的论点真的站得住脚。
以您给出的示例为例:“getNumberOfSkinCareEligibleItemsWithinTransaction”。在我看来,它只做一件事:它计算交易中属于某个类别的项目数量。当然,如果不查看该方法的实际代码,我无法判断,但这对我来说听起来是个好方法。
另一方面,我看到很多方法名称非常简洁明了,它们的工作量很大,例如“processSale”或曾经流行的“doStuff”。
我认为给出一个关于方法名称长度的硬性规则会很困难,但目标应该是:足够长以传达函数的功能,足够短以易于阅读。在这个例子中,我认为“getSkinCareCount”可能就足够了。问题是你需要区分什么。如果您有一个函数计算交易中符合护肤条件的项目,而另一个函数计算其他项目中符合护肤条件的项目,那么“withinTransactions”会增加价值。但是,如果在交易之外谈论这些项目没有任何意义,那么用这些多余的信息来混淆名称是没有意义的。
第二,我认为假设任何可管理长度的名称都能准确地告诉您该函数在除了最微不足道的情况之外的所有情况下的作用是非常不现实的。一个现实的目标是让一个名字给读者一个线索,并且可以在以后记住。就像,如果我试图找到计算我们需要消耗多少反物质才能达到翘曲速度的代码,如果我查看函数名称并看到“calibrateTransporter”、“firePhasers”和“calcAntimatterBurn”,很明显前两个不是,但第三个可能是。如果我检查并发现那确实是我正在寻找的那个,那么当我明天回来继续解决这个问题时,很容易记住这一点。这已经足够了。
三个相似的长名称比短名称更容易混淆。如果我有两个名为“calcSalesmanPay”和“calcGeekPay”的函数,我可以快速猜出哪个是哪个。但是,如果它们被称为“calculateMonthlyCheckAmountForSalesmanForExportToAccountingSystemAndReconciliation”和“calculateMonthlyCheckAmountForProgrammersForExportToAccountingSystemAndReconciliation”,我必须研究名称以查看哪个是哪个。在这种情况下,名称中的额外信息可能会适得其反。它将半秒思考变成了 30 秒思考。
【讨论】:
+1 表示这个糟糕的答案已经受到影响。【参考方案9】:按照您希望的方式设计您的界面,并使实现匹配。
例如,也许我会把它写成
getTransaction().getItems(SKIN_CARE).getEligible().size()
或使用 Java 8 流:
getTransaction().getItems().stream()
.filter(item -> item.getType() == SKIN_CARE)
.filter(item -> item.isEligible())
.count();
【讨论】:
【参考方案10】:我的规则如下:如果一个名字太长以至于它必须单独出现在一行,那么它就太长了。 (实际上,这意味着我很少超过 20 个字符。)
这是基于研究表明可见的垂直代码行数与编码速度/有效性正相关。如果类/方法名称开始显着损害这一点,那么它们就太长了。
在声明方法/类的位置添加注释,如果您想详细说明它的用途,让 IDE 带您到那里。
【讨论】:
我喜欢这样的规则。只要您记住您/您的团队是随机编造的,一切都很好。另一方面,我不能对此表示赞同,因为“研究展示”实际上需要一个指向该研究的链接,或者有关它的东西......【参考方案11】:方法本身的长度可能是一个更好的指标,它是否做得太多,即使这样也只能给你一个粗略的想法。你应该力求简洁,但描述性更重要。如果您不能用较短的名称传达相同的含义,那么名称本身可能还可以。
【讨论】:
【参考方案12】:下次你要写方法名的时候,想想下面的引用
"The man who is going to maintain your code is a phyco who knows where you stay"
【讨论】:
幸好他只是海藻而不是“精神病”【参考方案13】:那个方法名肯定太长了。当我阅读如此大小的方法名称时,我的思绪往往会徘徊。这就像阅读一个没有空格的句子。
就个人而言,我更喜欢方法中的单词越少越好。如果包和类名可以传达含义,您将得到帮助。 如果类的职责很简洁,就不需要大方法名了。我很好奇为什么会出现“WithinTransaction”。
“getNumberOfSkinCareEligibleItemsWithinTransaction”可能变成:
com.mycompany.app.product.SkinCareQuery.getNumEligibleItems();
然后在使用时,该方法可能看起来像“query.getNumEligibleItems()”
【讨论】:
【参考方案14】:变量名太长,因为较短的名称可以提高整个程序或程序重要部分的代码可读性。
如果更长的名称允许您传达有关值的更多信息。但是,如果名称太长,则会使代码混乱并降低理解其余代码的能力。这通常通过导致换行并将其他代码行推离页面而发生。
诀窍在于确定哪个会提供更好的可读性。如果变量在很短的空间内经常或多次使用,最好给它一个简短的名称并使用注释来澄清。读者可以轻松地参考评论。如果变量在整个程序中经常使用,经常作为参数或在其他复杂的操作中使用,最好将名称删减,或使用首字母缩略词来提醒读者。如果他们忘记了含义,他们总是可以通过变量声明引用注释。
这不是一个容易的权衡,因为您必须考虑代码阅读器可能试图理解的内容,并且还要考虑代码将如何随着时间的推移而变化和增长。这就是为什么命名很难。
可读性是为什么可以使用 i 作为循环计数器而不是 DescriptiveLoopCounterName 的原因。因为这是变量最常见的用途,所以您可以用最少的屏幕空间来解释它存在的原因。较长的名称只会浪费时间,让您更难理解您是如何测试循环条件或索引到数组中的。
另一方面,如果函数或变量在复杂操作中很少使用,例如传递给多参数函数调用,则您可以给它一个过于描述性的名称。
【讨论】:
【参考方案15】:与任何其他语言一样:当它不再描述函数执行的单个操作时。
【讨论】:
【参考方案16】:我会说使用好的答案的组合并且是合理的。
完整、清晰、易读地描述该方法的作用。
如果方法名称看起来太长——重构方法以减少工作量。
【讨论】:
【参考方案17】:当方法的名称换行到另一行并且对该方法的调用是该行中唯一的内容并且开始非常接近边缘时,这太长了。您必须考虑将使用它的人的平均屏幕尺寸。
但是!如果名字看起来太长,那么它可能太长了。解决它的方法是编写代码,使您在上下文中并且名称很短但在其他上下文中重复。这就像你可以用英语说“她”或“他”而不是某人的全名。
【讨论】:
【参考方案18】:如果过于冗长地解释事情的内容,那就太长了。
例如,这些名称在功能上是等效的。
在 Java 中:java.sql.SQLIntegrityConstraintViolationException
在 Python/Django 中:django.db.IntegrityError
问问自己,在一个 SQL/db 包中,你还能想出多少种完整性错误? ;)
因此db.IntegrityError
就足够了。
【讨论】:
你总是可以反过来争论。当它冗长地解释事情是什么时,显然很清楚该方法做什么,否则可能会引起混淆并可能引发对该方法的错误使用。【参考方案19】:标识符名称太长,超出 Java 编译器可以处理的长度。
【讨论】:
什么?!我不明白为什么我因此而被否决。这个问题没有要求一个必要条件,只是一个充分条件!【参考方案20】:这里有两种方式或观点:一种是方法名有多长其实并不重要,只要尽可能描述性地描述方法正在做什么(Java最佳实践基本规则) )。另一方面,我同意flybywire 的帖子。我们应该利用我们的智慧来尽量减少方法名称,但不降低它的描述性。描述性更重要:)
【讨论】:
【参考方案21】:如果名称太长:
阅读时间超过 1 秒 占用的 RAM 超过了为 JVM 分配的 RAM 是不是有些荒谬的名字 如果一个更短的名字很有意义 如果它在您的 IDE 中环绕老实说,这个名称只需要向开发人员传达其目的,他们将把它用作公共 API 方法,或者在您离开时必须维护代码。只要记住 KISS(保持简单愚蠢)
【讨论】:
以上是关于什么时候 Java 方法名太长了? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章