Quando um nome de método Java é muito longo? [fechadas]

173

Nas últimas semanas, eu vi alguns caras usando nomes muito longos para um Método ou Classe (50 caracteres), isso geralmente é sob a premissa de que melhora a legibilidade, minha opinião é que um nome longo como esse é um indicador de que estamos tentando fazer muito ou muito em uma classe de método se precisarmos de um nome tão longo, no entanto, eu queria saber o que vocês acham disso.

Um exemplo é:

getNumberOfSkinCareEligibleItemsWithinTransaction
MexicanHacker
fonte
19
SIM, é um "cheiro de código" ... c2.com/cgi/wiki?LongMethodSmell
Dan Rosenstark
23
Quando tem> 666 caracteres, você sabe que tem um problema.
Thomas Eding
8
@ yar no seu exemplo, o oposto de "Método Longo" é "Método Curto", que é considerado uma coisa boa. Portanto, obviamente, não está se referindo ao nome do método; está se referindo a linhas de código (ou algo semelhante). por exemplo, f()é muito curta função, mas certamente não é uma boa prática ... e algo que você deve dizer a alguns matemáticos de programação lá fora :)
sfussenegger
3
@sfussenegger, é verdade. Mas estou apostando em uma correlação entre o comprimento do nome do método e o comprimento do método. f()pode não ser uma ótima função, mas esse $()cara é como uma estrela do rock no mundo dos métodos Javascript.
Dan Rosenstark
7
@ yar, o link que você forneceu se referiu ao comprimento do método em linhas, não ao comprimento do método nome .
Thorbjørn Ravn Andersen

Respostas:

398

Um nome em Java ou qualquer outra linguagem é muito longo quando existe um nome mais curto que transmite igualmente o comportamento do método.

JaredPar
fonte
65
Matematicamente elegante.
Ricket
304
Portanto, por exemplo, boolean doesShorterNameExistThatEquallyConvaysTheBehaviorOfTheMethod(String s)deve ser refatorado para boolean isTooLong(String s).
z5h 9/02/10
6
Não concordo totalmente, pois você não apenas deseja transmitir o comportamento, mas também mantém a convenção do projeto e do idioma. Então, em Python você pode dizer, eligible_items_cntmas em Java você costuma dizer getEligibleItemsCount.
fly-by-wire
17
@flybywire: qualquer convenção que faça você escrever nomes excessivamente longos é um benefício duvidoso.
MAK
20
@MAK @ S. Lott que sobre getLength()vs. length()? Gosto muito de olhar para preenchimentos automáticos depois de digitar 'get' ou 'set' - então, nesse caso, prefiro convenção do que concisão.
Sfussenegger
202

Algumas técnicas para reduzir o comprimento dos nomes dos métodos:

  1. Se todo o seu programa, classe ou módulo for sobre 'itens de cuidados com a pele', você poderá descartar os cuidados com a pele. Por exemplo, se sua classe é chamada SkinCareUtils, isso leva você agetNumberOfEligibleItemsWithinTransaction

  2. Você pode mudar dentro para dentro ,getNumberOfEligibleItemsInTransaction

  3. Você pode alterar Transação para Tx, o que leva você a getNumberOfEligibleItemsInTx.

  4. Ou, se o método aceitar um parâmetro do tipo, Transactionvocê poderá descartar o InTx completamente:getNumberOfEligibleItems

  5. Você altera o númeroDe por contagem: getEligibleItemsCount

Agora isso é muito razoável. E é 60% menor.

flybywire
fonte
11
adicionalmente, 5) vai colocar getEligibleItems()e getEligibleItemsCount()ao lado do outro em listas ordenados alfabeticamente (por exemplo, o preenchimento automático ou javadoc)
sfussenegger
4
E, como geralmente é verdade, o nome mais curto se encaixa na regra do haiku.
Sal
2
@mercator O uso de uma convenção padrão como getEligibleItems sobre countEligibleItems reduz a chance de ambiguidade na declaração. O menos ambíguo quanto ao que o método deve fazer aumenta a legibilidade. Sem se aprofundar no método, um método que "conta" é menos claro do que o que um método "obtém" realiza a longo prazo.
Bill
53
Eu não gosto de abbr como Tx, Cnt, grphe assim por diante ... (btw, Txé a abreviação de "Transmission" ou "Transmissor")
Meinersbur
14
Sim, eu concordei com você até você decidir usar "Tx".
Ponkadoodle 28/05
183

Apenas para variar, uma resposta não subjetiva: 65536 caracteres.

A.java:1: A representação UTF8 para a cadeia "xxxxxxxxxxxxxxxxxxxxxx ..." é muito longa para o conjunto constante

;-)

Mark Byers
fonte
4
yeah seu tempo demais quando a JVM não posso lidar com ele não mo :)
Anurag
35
+1 para A resposta literal.
Sal
37
Tecnicamente, a especificação da linguagem Java não tem um limite superior para o comprimento do identificador. Essa é uma limitação da sua implementação da JVM. Felicidades!
Uckelman
13
O compilador da Sun aparentemente não está de acordo com as especificações. java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 diz: "Um identificador é uma sequência de tamanho ilimitado ..."
Michael Myers
6
A especificação JVM não tem um limite superior, como a mensagem de erro aponta. A representação do conjunto constante de utf8's é limitada a 2 ^ 16 bytes especificados aqui . Os nomes de classes e métodos devem ser armazenados como utf8 no pool constante.
thejoshwolfe 12/08
42

Concordo com todos: os nomes dos métodos não devem ser muito longos. Eu quero adicionar uma exceção, porém:

Os nomes dos métodos de teste JUnit, no entanto, podem ser longos e devem se parecer com sentenças.

Por quê?

  • Porque eles não são chamados em outro código.
  • Porque eles são usados ​​como nomes de teste.
  • Porque eles podem ser escritos como frases que descrevem requisitos. (Por exemplo, usando o AgileDox )

Exemplo:

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

Consulte " Design orientado a comportamento " para obter mais informações sobre essa idéia.

Epaga
fonte
5
+1 Eu concordo com isso e também é o que estou fazendo, embora os métodos JUnit 4 não sejam mais necessários para começar test, isso também abre a possibilidade de usar should: como dialogShouldCloseWhenTheRedButtonIsPressedTwice(). Ou você pode chamar a classe de teste DialogShoulde, em seguida, o método closeWhenTheRedButtonIsPressedTwice(), de modo a ler-los juntos: DialogShould.closeWhenTheRedButtonIsPressedTwice().
Stivlo
Enquanto eu concordo, também sugiro que uma sentença muito longa possa sugerir um teste que está fazendo muito!
precisa
17

O contexto "... WithinTransaction" deve ser óbvio. É disso que se trata a orientação a objetos.

O método faz parte de uma classe. Se a classe não significa "Transação" - e se isso não o impede de dizer "Dentro de Transação" o tempo todo, você tem problemas.

S.Lott
fonte
2
Pode levar algum tipo de parâmetro de transação também
willcodejavaforfood
3
Como você pode ver pela resposta com a melhor pontuação acima, opte pela simplicidade do interior, em vez dos conselhos de OO. +1
Dan Rosenstark
@ yar As pessoas nunca estão erradas.
CurtainDog
12

Eu costumo usar a regra haiku para nomes:

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

Estas são regras práticas para nomes máximos. Eu violei isso apenas quando melhora a legibilidade. Algo como recalculateMortgageInterest (currentRate, quoteSet ...) é melhor que recalculateMortgageInterestRate ou recalculateMortgageInterestRateFromSet, pois o fato de envolver taxas e um conjunto de cotações deve ficar bem claro nos documentos incorporados, como javadoc ou equivalente no .NET.

NOTA: Não é um haiku real, pois é 7-5-7 em vez de 5-7-5. Mas ainda prefiro chamá-lo de haiku.

sal
fonte
13
As classes obtêm sete, variáveis ​​menores que cinco, sete para o resto #
James
8
"variáveis no máximo cinco" (menos de cinco anos não é preciso)
Jason S
Nomes menores podem levar a menor legibilidade do código.
precisa saber é o seguinte
10

Java tem uma cultura de encorajar nomes longos, talvez porque os IDEs tenham um bom preenchimento automático.

Este site diz que o nome de classe mais longo no JRE InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedStatetem 92 caracteres.

Quanto ao nome do método mais longo, encontrei este supportsDataDefinitionAndDataManipulationTransactions, com 52 caracteres.

flybywire
fonte
20
Parece que essa classe foi nomeada pelas pessoas nomeadas contratadas pelo Departamento de Departamento de Redundância para nomear coisas no Departamento de Departamento de Redundância.
Michael Madsen
1
@MichaelMadsen: É realmente redundante ou está descrevendo um quadro aninhado dentro de outro quadro?
endolith 4/09/12
O PEP-8 gostaria de uma palavra com esse nome de classe.
Mateen Ulhaq
9

Nunca use uma palavra longa quando uma diminuta for suficiente.

Eu não acho que sua tese de "comprimento do nome do método é proporcional ao comprimento do método" realmente retém a água.

Tome o exemplo que você fornece: "getNumberOfSkinCareEligibleItemsWithinTransaction". Parece-me que faz apenas uma coisa: conta o número de itens em uma transação que se enquadram em uma determinada categoria. É claro que não posso julgar sem ver o código real do método, mas isso me parece um bom método.

Por outro lado, vi muitos métodos com nomes muito curtos e concisos que dão muito trabalho, como "processSale" ou o sempre popular "doStuff".

Eu acho que seria difícil estabelecer uma regra rígida sobre o tamanho do nome do método, mas o objetivo deve ser: longo o suficiente para transmitir o que a função faz, curto o suficiente para ser legível. Neste exemplo, eu acho que "getSkinCareCount" provavelmente seria suficiente. A questão é o que você precisa distinguir. Se você tem uma função que conta itens elegíveis para cuidados com a pele em transações e outra que conta itens elegíveis para cuidados com a pele em outra coisa, "dentro de Transações" agrega valor. Mas se isso não significa nada para falar sobre esses itens fora de uma transação, não faz sentido atrapalhar o nome com essas informações supérfluas.

Segundo, acho que não é realista supor que um nome de qualquer tamanho gerenciável lhe diga exatamente o que a função faz em todos os casos, exceto nos mais triviais. Um objetivo realista é criar um nome que dê ao leitor uma pista e que possa ser lembrado mais tarde. Por exemplo, se estou tentando encontrar o código que calcula quanta antimatéria precisamos consumir para atingir a velocidade da dobra, se eu olhar os nomes das funções e vir "calibrateTransporter", "firePhasers" e "calcAntimatterBurn", é bem claro que os dois primeiros não são, mas o terceiro pode ser. Se eu verificar e descobrir que esse é realmente o que estou procurando, será fácil lembrar que, quando voltar amanhã para trabalhar um pouco mais sobre esse problema. Isso é bom o suficiente.

Três, nomes longos semelhantes são mais confusos do que nomes abreviados. Se eu tiver duas funções chamadas "calcSalesmanPay" e "calcGeekPay", posso adivinhar qual é qual rapidamente. Mas se eles são chamados "calculeMonthlyCheckAmountForSalesmanForExportToAccountingSystemAndReconciliation" e "calculeMonthlyCheckAmountForProgrammersForExportToAccountingSystemAndReconciliation", preciso estudar os nomes para ver qual é qual. As informações extras no nome provavelmente são contraproducentes nesses casos. Transforma um pensamento de meio segundo em um pensamento de 30 segundos.

Jay
fonte
+1 para esta resposta ruim que sofreu.
Dan Rosenstark
7

Projete sua interface da maneira que deseja e faça a implementação corresponder.

Por exemplo, talvez eu escreva isso como

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

ou com fluxos Java 8:

getTransaction().getItems().stream()
    .filter(item -> item.getType() == SKIN_CARE)
    .filter(item -> item.isEligible())
    .count();
Christoffer Hammarström
fonte
6

Minha regra é a seguinte: se um nome é tão longo que precisa aparecer em uma linha própria, é muito longo. (Na prática, isso significa que raramente estou acima de 20 caracteres.)

Isso se baseia em pesquisas que mostram que o número de linhas verticais de código visíveis se correlaciona positivamente com a velocidade / eficácia da codificação. Se os nomes de classe / método começarem a prejudicar significativamente isso, eles serão muito longos.

Adicione um comentário em que o método / classe é declarado e deixe o IDE levá-lo até lá, se você quiser uma descrição longa do que serve.

Rex Kerr
fonte
Eu gosto de regras assim. Desde que você tenha em mente que você / sua equipe os criaram aleatoriamente, tudo ficará bem. Por outro lado, não posso upvote isso porque "uma pesquisa mostrando" seria realmente precisa de um link para a pesquisa, ou algo sobre isso ...
Dan Rosenstark
5

O tamanho do método em si provavelmente é um indicador melhor de que ele está fazendo muito, e mesmo isso apenas lhe dá uma idéia aproximada. Você deve procurar concisão, mas a descrição é mais importante. Se você não pode transmitir o mesmo significado em um nome mais curto, provavelmente o nome em si provavelmente está correto.

Bill the Lizard
fonte
3

Quando você escrever um nome de método da próxima vez, pense na citação abaixo

"The man who is going to maintain your code is a phyco who knows where you stay"
Sreejesh
fonte
13
Ainda bem que ele está apenas algas e não um 'psico'
StingyJack
2

Esse nome do método é definitivamente muito longo. Minha mente tende a vagar quando estou lendo nomes de métodos de tamanho tão grande. É como ler uma frase sem espaços.

Pessoalmente, prefiro o mínimo de palavras possível nos métodos. Você será ajudado se o nome do pacote e da classe puder transmitir significado. Se a responsabilidade da classe é muito concisa , não há necessidade de um nome de método gigante. Estou curioso para saber por que "WithinTransaction" está lá.

"getNumberOfSkinCareEligibleItemsWithinTransaction" pode se tornar:

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

Então, quando estiver em uso, o método poderá se parecer com "query.getNumEligibleItems ()"

Jesse
fonte
2

Um nome de variável é muito longo quando um nome mais curto permitirá uma melhor legibilidade do código em todo o programa ou nas partes importantes do programa.

Se um nome mais longo permitir transmitir mais informações sobre um valor. No entanto, se um nome for muito longo, ele sobrecarregará o código e reduzirá a capacidade de compreender o restante do código. Isso normalmente ocorre causando quebra de linha e empurrando outras linhas de código para fora da página.

O truque é determinar qual oferecerá melhor legibilidade. Se a variável for usada frequentemente ou várias vezes em um curto espaço de espaço, pode ser melhor dar um nome curto e usar um esclarecimento de comentário. O leitor pode consultar o comentário facilmente. Se a variável for usada frequentemente em todo o programa, como parâmetro ou em outras operações complicadas, talvez seja melhor aparar o nome ou usar siglas como lembrete para o leitor. Eles sempre podem fazer referência a um comentário pela declaração da variável se esquecerem o significado.

Não é fácil fazer isso, pois é necessário considerar o que o leitor de código provavelmente está tentando compreender e também levar em consideração como o código mudará e crescerá com o tempo. É por isso que nomear as coisas é difícil.

A legibilidade é o motivo pelo qual é aceitável usar i como um contador de loop, em vez de DescriptiveLoopCounterName. Como esse é o uso mais comum para uma variável, você pode gastar a menor quantidade de espaço na tela explicando por que ela existe. O nome mais longo vai desperdiçar tempo, tornando mais difícil entender como você está testando a condição do loop ou indexando em uma matriz.

No outro extremo do espectro, se uma função ou variável for usada raramente como em uma operação complexa, como ser passada para uma chamada de função com vários parâmetros, você pode dar um nome excessivamente descritivo.

Ben Gartner
fonte
1

Como em qualquer outro idioma: quando não descreve mais a ação única que a função executa.

Kaz Dragon
fonte
1

Eu diria que use uma combinação das boas respostas e seja razoável.

Descreva de forma completa, clara e legível o que o método faz.

Se o nome do método parecer muito longo - refatorar o método para fazer menos.

Bill K
fonte
1

É muito longo quando o nome do método se agrupa em outra linha e a chamada para o método é a única coisa na linha e começa bem perto da margem. Você deve levar em consideração o tamanho médio da tela das pessoas que a usarão.

Mas! Se o nome parece muito longo, provavelmente é muito longo. A maneira de contornar isso é escrever seu código de forma que você esteja dentro de um contexto e o nome seja curto, mas duplicado em outros contextos. É como quando você pode dizer "ela" ou "ele" em inglês, em vez do nome completo de alguém.

Brian T Hannan
fonte
1

É muito longo quando explica de maneira muito detalhada o que é a coisa.

Por exemplo, esses nomes são funcionalmente equivalentes.

em Java: java.sql.SQLIntegrityConstraintViolationException

em Python / Django: django.db.IntegrityError

Pergunte a si mesmo, em um pacote SQL / db, quantos outros tipos de erros de integridade você pode encontrar? ;) Portanto, db.IntegrityErroré suficiente.

vdboor
fonte
Você sempre pode discutir o contrário. Quando é explicado explicitamente do que se trata, fica obviamente claro o que o método faz, caso contrário, pode causar confusão e provocar o uso incorreto do método.
Jonas Geiregat # 03
0

Um nome de identificador é muito longo quando excede o comprimento que seu compilador Java pode suportar.

uckelman
fonte
3
O que?! Não vejo por que fui votado para isso. A pergunta não pedia uma condição necessária, apenas uma condição suficiente!
Uckelman
0

Existem duas maneiras ou pontos de vista aqui: Uma é que realmente não importa quanto tempo o nome do método seja, desde que seja o mais descritivo possível para descrever o que o método está fazendo (regra básica das melhores práticas de Java). Por outro lado, concordo com o post flybywire. Deveríamos usar nossa inteligência para tentar reduzir o máximo possível o nome do método, mas sem reduzir sua descrição. A descrição é mais importante :)

HackerGil
fonte
0

Um nome é muito longo se:

  • Leva mais de 1 segundo para ler
  • Consome mais RAM do que você aloca para sua JVM
  • É algo absurdamente chamado
  • Se um nome mais curto fizer todo sentido
  • Se envolver o seu IDE

Honestamente, o nome só precisa transmitir seu objetivo aos Desenvolvedores que o utilizarão como um método público da API ou terão que manter o código quando sair. Apenas lembre-se do KISS (mantenha-o estúpido)

Paul Gregoire
fonte