Nomes longos são muito longos

Olá Habr! Apresento a você a tradução do artigo "Long Names Are Long" de Bob Nystrom.


Uma das coisas inteligentes que o Google faz é uma rigorosa revisão de código. Cada alteração, antes que você possa chegar à ramificação principal, é considerada em pelo menos duas direções. Primeiro, alguém da equipe faz uma verificação de rotina para garantir que o código faça o que deveria.


Porém, o segundo passo ocorre quando a legibilidade do código é verificada. Isso garante que outros desenvolvedores possam oferecer suporte a esse código no futuro. Esse código é fácil de entender e manter? Esse código corresponde ao estilo e aos idiomas do idioma? O código está bem documentado?


O uso da linguagem Dart no Google está gradualmente ganhando força, e lidei muito com essa revisão de código. Para um desenvolvedor de idiomas, esse é um processo muito interessante. Tenho uma visão em primeira mão de como as pessoas usam o Dart, o que é realmente útil para o seu desenvolvimento. Tenho uma ideia mais clara de quais erros são comuns e quais funções são muito usadas. Eu me sinto como um etnógrafo, um diário sobre a vida dos nativos.


Mas, de qualquer forma, esse não é o caso. Maldito seja, nem são dardos. O que eu quero falar é sobre o que vejo em muitos códigos e o que me deixa louco: nomes muito longos .


Sim, os nomes podem ser muito curtos. Naqueles dias em que C exigia que apenas identificadores externos fossem exclusivos até os seis primeiros caracteres; quando o preenchimento automático ainda não foi inventado; quando cada toque de tecla era como subir morro acima na neve - isso era um problema. Fico feliz que agora vivemos em uma utopia futurista, onde peidos de teclado como p , idxcrpm e x3 são raros.


Mas o pêndulo girou demais na outra direção. Não precisamos ser Hemingway, também não precisamos ser o Tennessee Williams. Nomes excessivamente longos também prejudicam a clareza do código em que são usados. Nomes de variáveis ​​muito longos ofuscam as operações que você executa nelas. O código torna-se difícil de digitalizar visualmente. Para atender aos requisitos de largura do código, aparecem quebras de linha adicionais que interrompem o fluxo lógico do código. Nomes longos de métodos ocultam suas listas de argumentos igualmente importantes. Variáveis ​​longas são irritantes com a reutilização, o que leva a esticar cadeias de métodos ou cascatas.


Vi nomes de variáveis ​​com mais de 60 caracteres. Você pode colocar um haiku ou koan lá (e provavelmente esclarecer o leitor mais do que o nome que você escolher). Mas não tema, eu estou aqui para ajudar.


Escolhendo um bom nome


Qualquer nome na programação tem dois objetivos:


  • O nome deve estar claro : você precisa saber a que se refere.
  • O nome deve ser preciso : você precisa saber ao que ele não se aplica.

Uma vez que o nome tenha atingido esses objetivos, quaisquer caracteres adicionais terão peso morto. Aqui estão algumas diretrizes que eu uso quando nomeio coisas no meu código:


1. Evite palavras especificadas explicitamente em um tipo de variável ou parâmetro


Se seu idioma possui um sistema de tipo estático, os usuários geralmente sabem o tipo da variável. Como regra, os métodos são bastante curtos, portanto, mesmo olhando para uma variável local onde o tipo não pode ser assumido imediatamente, ou em uma revisão de código, ou em algum lugar onde a análise estática de código não pode entrar - raramente precisa de um pouco mais do que observar algumas linhas acima para determinar o tipo de variável.


Diante disso, não é necessário indicar o tipo no nome da variável. Acabamos de abandonar a notação húngara . Deixe de lado e esqueça :


 // : String nameString; DockableModelessWindow dockableModelessWindow; // : String name; DockableModelessWindow window; 

Especialmente para coleções, é quase sempre melhor usar um substantivo plural que descreva o conteúdo do que um substantivo singular que descreva uma coleção . Se o leitor se importa mais com o que está na coleção, o título deve refletir isso.


 // : List<DateTime> holidayDateList; Map<Employee, Role> employeeRoleHashMap; // : List<DateTime> holidays; Map<Employee, Role> employeeRoles; 

Isso também se aplica aos nomes dos métodos. O nome do método não precisa descrever seus parâmetros ou seus tipos - a lista de parâmetros fará isso por você.


 // : mergeTableCells(List<TableCell> cells) sortEventsUsingComparator(List<Event> events, Comparator<Event> comparator) // : merge(List<TableCell> cells) sort(List<Event> events, Comparator<Event> comparator) 

Isso resulta em chamadas sendo lidas melhor que isso:


 mergeTableCells(tableCells); sortEventsUsingComparator(events, comparator); 

Sou apenas eu, ou há um eco aqui?


2. Evite palavras que não desambiguem o nome


Algumas pessoas tendem a inserir tudo o que sabem sobre algo no nome de uma variável. Lembre-se de que o nome é um identificador : indica o local onde está definido. Este não é um catálogo exaustivo de tudo o que o leitor pode querer saber sobre o objeto. A definição tornará melhor. O nome só o direcionará para lá.


Quando vejo o nome recentlyUpdatedAnnualSalesBid , pergunto-me:


  • Existem pedidos de vendas anuais atualizados que não sejam os mais recentes?
  • Existem solicitações de vendas anuais recentes que não foram atualizadas?
  • Existem aplicativos anuais de não vendas atualizados recentemente?
  • Existem dados de vendas anuais atualizados recentemente que não são lances?

Se a resposta for "não" a pelo menos uma dessas perguntas, isso geralmente indica uma palavra extra no nome.


 // : finalBattleMostDangerousBossMonster; weaklingFirstEncounterMonster; // : boss; firstMonster; 

Obviamente, você pode ir longe demais. Encurtar o primeiro exemplo para bid pode ser muito vago. Mas em caso de dúvida, deixe assim. Você sempre pode adicionar uma classificação adicional posteriormente se o nome for a causa do conflito ou for impreciso. No entanto, é improvável que você volte mais tarde para aparar todo esse excesso de gordura.


3. Evite palavras claras do contexto.


Eu posso usar a palavra "I" neste parágrafo, porque você sabe que este texto é de Bob Nystrom. Não preciso repetir constantemente "Bob Nystrom" aqui (apesar da tentação de Bob Nystrom de fortalecer Bob Nystrom dessa maneira). O código funciona exatamente da mesma maneira. Um método ou campo ocorre no contexto de uma classe. Uma variável ocorre no contexto de um método. Tome esse contexto como garantido e não o repita.


 // : class AnnualHolidaySale { int _annualSaleRebate; void promoteHolidaySale() { ... } } // : class AnnualHolidaySale { int _rebate; void promote() { ... } } 

Na prática, isso significa que, quanto mais profundo o nome é incorporado, mais envolvente é o contexto. Como resultado, acontece que esse nome será mais curto. Como resultado, você pode ver um padrão: identificadores que estão em uma área mais estreita têm nomes mais curtos.


4. Evite palavras que não significam nada.


Muitas vezes vejo esse erro na indústria de jogos. Alguns desenvolvedores sucumbem à tentação e inflam os nomes de suas variáveis, adicionando palavras de "negócios sérios". Eles acreditam que isso torna seu código mais importante e, consequentemente, os torna mais importantes.


Na maioria dos casos, essas palavras não carregam nenhuma informação significativa para o desenvolvedor. Normalmente, as suspeitas se baseiam em palavras como: data , state , amount , value , manager , engine , object , entity e instance .


Um bom nome pinta uma imagem na mente do leitor. Chamando qualquer coisa de "gerente", não fornecemos ao leitor nenhuma informação sobre o que esse objeto deve fazer. Faz um cálculo de avaliação de desempenho? Nomeia promoção para seus funcionários?


Pergunte a si mesmo: "Esse nome terá o mesmo significado se eu retirar essa palavra?" Se sim, então a palavra não importa - expulse da ilha.


Aplicando o manual a ... waffles


Para ter uma idéia de como essas regras funcionam na prática, aqui está um exemplo que viola todas elas. Este exemplo artificial é muito semelhante ao código real, que muitas vezes me ocorre na revisão de código.


 class DeliciousBelgianWaffleObject { void garnishDeliciousBelgianWaffleWithStrawberryList( List<Strawberry> strawberryList) { ... } } 

Graças ao tipo de parâmetro, sabemos que o método aceita uma lista de morangos (nº 1). Vamos cortar essa informação de um nome:


 class DeliciousBelgianWaffleObject { void garnishDeliciousBelgianWaffle( List<Strawberry> strawberries) { ... } } 

Se não houver waffles belgas de mau gosto ou de outras nacionalidades no programa, podemos descartar com segurança todos os adjetivos (nº 2):


 class WaffleObject { void garnishWaffle(List<Strawberry> strawberries) { ... } } 

Esse método está dentro do WaffleObject , portanto, a partir do contexto, sabemos o que exatamente ele irá decorar (# 3):


 class WaffleObject { void garnish(List<Strawberry> strawberries) { ... } } 

Obviamente, este é um objeto. Tudo é um objeto na programação orientada a objetos (# 4):


 class Waffle { void garnish(List<Strawberry> strawberries) { ... } } 

Agora muito melhor.


Eu acho que essas são recomendações bem simples. Você tem o direito de pensar que é inútil se preocupar com essas insignificâncias. Mas acredito que nomear é uma das tarefas mais fundamentais que realizamos ao programar. Os nomes são a estrutura que impomos ao mar informe dos bits, que é o computador.

Source: https://habr.com/ru/post/pt450986/


All Articles