Alguém mais acha que nomear classes e métodos é uma das partes mais difíceis da programação? [fechadas]

275

Então, eu estou trabalhando nessa classe que deveria solicitar documentação de ajuda de um fornecedor por meio de um serviço da web. Tento nome dele DocumentRetriever, VendorDocRequester, DocGetter, mas eles simplesmente não parece certo. Acabei navegando no dictionary.com por meia hora tentando encontrar uma palavra adequada.

Começar a programar com nomes ruins é como ter um dia de cabelos muito ruins pela manhã, o resto do dia desce a partir daí. Me sente?

Haoest
fonte
2
Por que você quer uma aula, quando claramente precisa apenas de uma função? Verifique steve-yegge.blogspot.com/2006/03/… para obter o verbo como problema do nome da classe.
user51568
Ou siga em frente e refatorar quando finalmente souber como deve ser chamado.
Esteban Araya
16
Como você está nomeando ? : métodos : use verbos , como obter, definir, salvar, etc. classes e variáveis : use substantivos , como documento, usuário, contexto, etc. interfaces : use adjetivos , como imprimíveis, clonáveis, iteráveis, etc. Depois de ler este tópico, gosto da sugestão de Spolsky para classes e variáveis (usa substantivos) e da sugestão do TravisO para métodos (usa verbos). Também não crie objetos que terminem com 'er' .
Daniel Gasull
5
"Existem dois problemas difíceis na ciência da computação: invalidação de cache, convenções de nomenclatura e estouro silencioso".
Karakuri
6
@karakuri A versão que ouvi é "existem 2 problemas difíceis na ciência da computação: nomear e compensar por 1 erro".
Haoest 26/11/14

Respostas:

121

O que você está fazendo agora é bom, e eu recomendo que você mantenha sua sintaxe atual, sendo:

contexto + verbo + como

Eu uso esse método para nomear funções / métodos, procs armazenados em SQL etc. Mantendo essa sintaxe, ele manterá os painéis Intellisense / Code muito mais organizados. Então você deseja EmployeeGetByID () EmployeeAdd (), EmployeeDeleteByID (). Quando você usa uma sintaxe gramaticalmente mais correta, como GetEmployee (), AddEmployee (), verá que isso fica realmente confuso se você tiver vários Gets na mesma classe, pois as coisas não relacionadas serão agrupadas.

Eu pareço isso com a nomeação de arquivos com datas, você quer dizer 2009-01-07.log e não 1-7-2009.log porque, depois de vários, a ordem se torna totalmente inútil.

TravisO
fonte
28
Prefiro que o contexto seja deduzido do nome do tipo ao nomear métodos ... class EmployeeRepository {void Add (Employee employee); void Get (int id); void GetAll (); void GetAll (filtro Action <FilterCriteria>); } O que você acha?
Vyas Bharghava 7/01/09
5
Também ajuda se você tiver uma lista padrão de verbos "domésticos". Portanto, é sempre Obter e não Carregar / Ler / Recuperar / Selecionar / Localizar .... etc. #
Dead dead
2
Richard, você está correto nos cenários OOP, minha resposta recuou um pouco e foi mais uma sugestão geral de codificação. Eu acho que tecnicamente se aplica mais a idiomas não OOP. Employee.Add () e Employee.GetByID () seriam o melhor uso no OOP.
TravisO
6
Gosto do efeito Intellisense da sua sugestão, mas prefiro uma abordagem um pouco mais instruída. Então eu prefiro Employee.SetSupervisor () sobre Employee.SupervisorSet () porque ele lê (mais como Inglês natural.
Matthew Maravillas
12
Mas @TravisO, isso não soa bem em inglês. Você não recebe empregado, recebe um empregado. E se você tiver ações mais complexas envolvendo adjetivos, como InvalidateObsoleteQueries? QueriesInvalidateObsoleteé difícil de ler e não faz sentido. Além disso, em C #, especialmente no Resharper, a ordem alfabética é irrelevante. Se você começar a digitar "emp", ReSharper irá dar-lhe GetEmployee, SetEmployeee mesmo PopulateInactiveEmployeesList.
Ilya Kogan
54

Uma lição que aprendi é que, se você não consegue encontrar um nome para uma turma, quase sempre há algo errado com essa turma:

  • você não precisa disso
  • faz demais
Toon Krijthe
fonte
13
Ou faz muito pouco.
User51568
4
Obrigado, isso foi realmente relevante para mim.
Haoest
52

Uma boa convenção de nomenclatura deve minimizar o número de nomes possíveis que você pode usar para qualquer variável, classe, método ou função. Se houver apenas um nome possível, você nunca terá problemas para se lembrar dele.

Para funções e para classes singleton, examino a função para ver se sua função básica é transformar um tipo de coisa em outro tipo de coisa. Estou usando esse termo muito livremente, mas você descobrirá que um enorme número de funções que você escreve toma essencialmente algo de uma forma e produz algo de outra forma.

No seu caso, parece que sua classe transforma um URL em um documento. É um pouco estranho pensar dessa maneira, mas perfeitamente correto, e quando você começar a procurar esse padrão, verá em todos os lugares.

Quando encontro esse padrão, sempre nomeio a função x Fromy .

Como sua função transforma um URL em um documento, eu o chamaria

DocumentFromUrl

Esse padrão é notavelmente comum. Por exemplo:

atoi -> IntFromString
GetWindowWidth -> WidthInPixelsFromHwnd // or DxFromWnd if you like Hungarian
CreateProcess -> ProcessFromCommandLine

Você também pode usar UrlToDocumentse estiver mais confortável com esse pedido. Se você diz que x Fromy ou y Tox é provavelmente uma questão de gosto, mas prefiro a Fromordem, pois dessa forma o início do nome da função já diz qual tipo ele retorna.

Escolha uma convenção e cumpra-a. Se você for cuidadoso ao usar os mesmos nomes dos nomes das classes nas funções x Fromy , será muito mais fácil lembrar quais nomes você usou. Obviamente, esse padrão não funciona para tudo, mas funciona onde você está escrevendo um código que pode ser considerado "funcional".

Joel Spolsky
fonte
Um bom lembrete de que, em idiomas OOP, os nomes das classes nem sempre precisam ser substantivos, mas é aceitável que eles sejam "verbais" de vez em quando. Portanto, por que os praticantes de OOP costumam ser enganados (como a pessoa que faz a pergunta), uma vez que enfatizam demais que as aulas devem ser uma "coisa" no mundo real.
Ray
7
O xFromY-Convetion basicamente repete o que está no tipo de retorno e na lista de parâmetros: Foo fooFromBar (barra de barras). Depende de você se você chamar isso de consistência ou redendância.
Lena Schimmel
"No seu caso, parece que sua classe transforma um URL em um documento". Desde quando as classes deveriam "fazer" as coisas, em vez de representar conceitos?
user51568
6
@ Brian: é apenas redundante em um só lugar ... na declaração. Em qualquer outro lugar que você o use, é bom ter um pequeno lembrete dos tipos de dados. Torna o código mais legível sem precisar voltar à declaração.
Joel Spolsky
3
@ stefan- Em algumas linguagens como C # e Java, todo o código deve ser encapsulado em uma classe diferente de C ++. As funções não são cidadãos de primeira classe nesses idiomas se você deseja modularizar o código. Portanto, às vezes você acaba com uma classe que pode "fazer" coisas como uma função.
Ray
31

Às vezes, não existe um bom nome para uma classe ou método, isso acontece com todos nós. Muitas vezes, no entanto, a incapacidade de criar um nome pode ser uma dica de algo errado com seu design. Seu método tem muitas responsabilidades? Sua classe contém uma ideia coerente?

Brad Barker
fonte
3
Muito bom ponto, realmente.
Camilo Martin
27

Tópico 1:

function programming_job(){
    while (i make classes){
         Give each class a name quickly; always fairly long and descriptive.
         Implement and test each class to see what they really are. 
         while (not satisfied){
            Re-visit each class and make small adjustments 
         }
    }
}

Tópico 2:

while(true){
      if (any code smells bad){
           rework, rename until at least somewhat better
      }
}

Não há Thread.sleep (...) em qualquer lugar aqui.

krosenvold
fonte
24

Também passo muito tempo me preocupando com os nomes de qualquer coisa que possa receber um nome quando estou programando. Eu diria que compensa muito bem. Às vezes, quando estou preso, deixo por um tempo e, durante uma pausa para o café, pergunto um pouco se alguém tem uma boa sugestão.

Para sua classe, eu sugiro VendorHelpDocRequester.

willcodejavaforfood
fonte
1
> VendorHelpDocRequester Good one. Na verdade, pesquisei no Google Solicitador em vez de Solicitante, ambas parecem palavras legítimas em inglês.
Haoest
1
Eu já fiz isso uma ou duas vezes, bem :)
willcodejavaforfood
1
Ter um verbo no nome da classe sempre soa errado para mim. Além disso, sempre leva a alguma duplicação no uso (ou seja:) VendorHelpDocRequester.request(). Eu preferiria apenas a forma plural como `VendorHelpDocs.request () '
Edson Medina
19

O livro Code Complete, de Steve Mcconnell, tem um bom capítulo sobre como nomear variáveis ​​/ classes / funções / ...

Emile Vrijdags
fonte
esse é um dos meus livros favoritos, recomendo
willcodejavaforfood
2
+1 para quem mencionar o Código Completo!
Richard Ev
15

Eu acho que isso é um efeito colateral.

Não é difícil dar nomes reais. O difícil é que o processo de nomeação o faz encarar o fato horrível de que você não tem idéia do que diabos está fazendo.

Nosredna
fonte
12

Na verdade, acabei de ouvir essa citação ontem, através do blog Signal vs. Noise, na 37Signals, e certamente concordo com isso:

"Existem apenas duas coisas difíceis na Ciência da Computação: invalidação de cache e nomeação de coisas." - Phil Karlton

Jonathan Schuster
fonte
simonwillison.net/2007/Jul/5/hard me levou a tbray.org/ongoing/When/200x/2005/12/23/UPI, que me levou a karlton.hamilton.com e karlton.hamilton.com/quotes /showallquotes.cgi , que não inclui a citação! (Mas reconheço # 5 de Scrum.)
Daryl Spitzer
1
"Duas coisas difíceis na Ciência da Computação: invalidação de cache, nomeação de coisas e erros pontuais".
Dan Lugg
7

É bom que seja difícil. Isso está forçando você a pensar sobre o problema e o que a classe realmente deve fazer. Bons nomes podem ajudar a levar a um bom design.

JW.
fonte
6

Acordado. Eu gosto de manter meus nomes e variáveis ​​de tipo o mais descritivos possível sem ser muito longo, mas às vezes há apenas um certo conceito para o qual você não consegue encontrar uma boa palavra.

Nesse caso, sempre me ajuda a pedir sugestões a um colega de trabalho - mesmo que elas não ajudem, geralmente me ajuda a pelo menos explicar em voz alta e fazer minhas rodas girarem.

Daniel Schaffer
fonte
6

Eu estava escrevendo sobre convenções de nomenclatura no mês passado: http://caseysoftware.com/blog/useful-naming-conventions

A essência disso:

verbAdjectiveNounStructure - com Structure e Adjective como partes opcionais

Para verbos , mantenho os verbos de ação: salve, exclua, notifique, atualize ou gere. De vez em quando, eu uso "processo", mas apenas para me referir especificamente a filas ou atrasos de trabalho.

Para substantivos , eu uso a classe ou o objeto com o qual interagimos. No web2project, isso geralmente é Tarefas ou Projetos. Se o Javascript estiver interagindo com a página, pode ser corpo ou tabela. O ponto é que o código descreve claramente o objeto com o qual ele está interagindo.

A estrutura é opcional porque é exclusiva para a situação. Uma tela de listagem pode solicitar uma lista ou uma matriz. Uma das principais funções usadas na lista de projetos do web2project é simplesmente getProjectList. Não modifica os dados subjacentes, apenas a representação dos dados.

Os adjetivos são algo completamente diferente. Eles são usados ​​como modificadores para o substantivo. Algo tão simples como getOpenProjects pode ser facilmente implementado com um getProjects e um parâmetro switch, mas isso tende a gerar métodos que exigem um pouco de entendimento dos dados e / ou estrutura subjacentes do objeto ... não necessariamente algo que você deseja incentivar. Por ter funções mais explícitas e específicas, você pode quebrar e ocultar completamente a implementação do código que a usa. Esse não é um dos pontos do OO?

CaseySoftware
fonte
4

Mais do que apenas nomear uma classe, criar uma estrutura de pacote apropriada pode ser um desafio difícil, mas gratificante. Você precisa considerar a separação das preocupações de seus módulos e como elas se relacionam com a visão do aplicativo.

Considere o layout do seu aplicativo agora:

  • Aplicativo
    • VendorDocRequester (leia do serviço da web e forneça dados)
    • VendorDocViewer (use o solicitante para fornecer documentos do fornecedor)

Atrevo-me a adivinhar que há muita coisa acontecendo em algumas aulas. Se você refatorar isso para uma abordagem mais baseada em MVC e permitir que pequenas classes lidem com tarefas individuais, você pode acabar com algo como:

  • Aplicativo
    • VendorDocs
      • Modelo
        • Documento (objeto simples que contém dados)
        • WebServiceConsumer (lidar com detalhes básicos em serviços da web)
      • Controlador
        • DatabaseAdapter (manipular persistência usando ORM ou outro método)
        • WebServiceAdapter (utilize o Consumer para pegar um documento e colá-lo no banco de dados)
      • Visão
        • HelpViewer (use DBAdapter para cuspir a documentação)

Em seguida, seus nomes de classe dependem do espaço para nome para fornecer o contexto completo. As próprias classes podem estar inerentemente relacionadas ao aplicativo sem precisar explicitamente dizer isso. Os nomes das classes são mais simples e fáceis de definir como resultado!

Outra sugestão muito importante: faça um favor a si mesmo e pegue uma cópia do Head First Design Patterns. É um livro fantástico e de fácil leitura que o ajudará a organizar seu aplicativo e escrever um código melhor. Apreciar os padrões de design o ajudará a entender que muitos dos problemas que você encontrou já foram resolvidos e você poderá incorporar as soluções ao seu código.

Mike Griffith
fonte
4

Leo Brodie, em seu livro "Thinking Forth", escreveu que a tarefa mais difícil para um programador era nomear as coisas bem, e afirmou que a ferramenta de programação mais importante é o tesauro.

Tente usar o dicionário de sinônimos em http://thesaurus.reference.com/ .

Além disso, não use a notação húngara EVER, evite abreviações e seja consistente.

Muitas felicidades.

Rob Williams
fonte
1
+1 com a nota de que você não deve usar o que é chamado de sistema húngaro; o aplicativo húngaro pode ser útil às vezes, especialmente em uma linguagem de programação sem um bom sistema de digitação.
User51568
Eu nunca ouvi falar da notação húngara de sistema x aplicativo, mas nem sempre é uma boa idéia em qualquer ambiente - você sempre deve nomear com base no QUE, não COMO, e o húngaro é totalmente sobre como.
Rob Williams
@RobWilliams Eu acho que eles estavam se referindo o artigo de Joel Spolsky
Alois Mahdal
1
@RobWilliams Além disso, você tem certeza sobre "Eu nunca ouvi falar de X vs Y, mas também nunca é uma boa idéia ..." ...? :)
Alois Mahdal
4

Em resumo:
concordo que bons nomes são importantes, mas acho que você não precisa encontrá-los antes de implementá-los a todo custo.

É claro que é melhor ter um bom nome desde o início. Mas se você não conseguir criar um em dois minutos, renomear mais tarde custará menos tempo e é a escolha certa do ponto de vista da produtividade.

Longo:
Geralmente, geralmente não vale a pena pensar muito em um nome antes de implementar. Se você implementar sua classe, nomeie-a "Foo" ou "Dsnfdkgx", enquanto implementa, você vê como deveria ter nomeado.

Especialmente no Java + Eclipse, renomear as coisas não é nada trabalhoso, pois lida cuidadosamente com todas as referências em todas as classes, avisa sobre colisões de nomes, etc. E enquanto a classe ainda não estiver no repositório de controle de versão, eu não acho que há algo errado em renomeá-lo 5 vezes.

Basicamente, é uma questão de como você pensa sobre a refatoração. Pessoalmente, eu gosto, embora às vezes chateie meus companheiros de equipe, pois eles acreditam em nunca tocar em um sistema em execução . E de tudo que você pode refatorar, mudar de nome é uma das coisas mais inofensivas que você pode fazer.

Lena Schimmel
fonte
3

Por que não o tipo HelpDocumentServiceClient, ou HelpDocumentClient ... não importa que seja um fornecedor, o ponto é que ele é um cliente de um serviço da Web que lida com documentos de Ajuda.

E sim, nomear é difícil.

JoshBerke
fonte
3

Existe apenas um nome sensato para essa classe:

HelpRequest

Não deixe que os detalhes da implementação o distraiam do significado.

Angus Glashier
fonte
Um ano e meio depois, eu estava prestes a sugerir HelpLibrarypara a aula, mas isso é pelo menos tão bom. Vale a pena ler as respostas primeiro!
Jeff Sternal
2

Invista em uma boa ferramenta de refatoração!

TGnat
fonte
ri muito. Às vezes, a refatoração não é a melhor opção (grandes projetos em C ++), mas certamente já recorri a ela antes. Às vezes eu só tenho que fazer as coisas, e os nomes me vêm depois.
9788 Steve S
2

Eu me ater ao básico: VerbNoun (argumentos). Exemplos: GetDoc (docID).

Não é preciso ser chique. Será fácil entender daqui a um ano, seja você ou outra pessoa.

LJ.
fonte
Enquanto isso lê bem, organiza-se mal porque é invertido. É melhor dizer DocGet () porque quando você também cria DocAdd () DocRemove () etc, todos eles aparecem juntos em uma lista. Seu método realmente mostra o quão feio fica quando você tem dezenas de Gets ou outros enfeites.
TravisO
Excelente sugestão, TravisO.
9139 Jon Smock
Eu não usaria um verbo para uma classe normalmente.
willcodejavaforfood
2

Para mim, não me importo com o tamanho de um método ou nome de classe, desde que seja descritivo e na biblioteca correta. Longe vão os dias em que você deve se lembrar de onde cada parte da API reside.

O Intelisense existe para todos os principais idiomas. Portanto, ao usar uma API de terceiros, gosto de usar o intelisense para a documentação, em vez de usar a documentação 'real'.

Com isso em mente, estou bem em criar um nome de método como

StevesPostOnMethodNamesBeingLongOrShort

Longo - mas e daí? Quem não usa telas de 24 polegadas hoje em dia!

Steve
fonte
1

Eu tenho que concordar que nomear é uma arte. Fica um pouco mais fácil se sua turma está seguindo um certo "padrão de desigh" (fábrica etc).

Otávio Décio
fonte
1

Esse é um dos motivos para ter um padrão de codificação. Ter um padrão tende a ajudar a criar nomes quando necessário. Isso ajuda a liberar sua mente para usar em outras coisas mais interessantes! (-:

Eu recomendo a leitura do capítulo relevante do Code Complete de Steve McConnell ( link da Amazon ), que inclui várias regras para ajudar na legibilidade e até na manutenção.

HTH

Felicidades,

Roubar

Rob Wells
fonte
1

Não, a depuração é a coisa mais difícil para mim! :-)

Guisado S
fonte
a depuração geralmente se resume a fazer a pergunta certa. Há esse jogo de números em que você precisa adivinhar um número de 1 a 1000. Se o seu palpite for muito baixo ou alto, o console informará e você terá apenas 10 tentativas. O que você faz?
Haoest
1

DocumentFetcher? É difícil dizer sem contexto.

Pode ajudar a agir como um matemático e a emprestar / inventar um léxico para o seu domínio à medida que avança: escolha palavras curtas e simples que sugerem o conceito sem explicá-lo sempre. Muitas vezes eu vejo frases longa Latinate que se transformaram em siglas, tornando você precisa de um dicionário para as siglas de qualquer maneira .

Darius Bacon
fonte
1

A linguagem usada para descrever o problema é a linguagem que você deve usar para as variáveis, métodos, objetos, classes, etc. Vagamente, os substantivos correspondem aos objetos e os verbos aos métodos. Se estiver faltando palavras para descrever o problema, também estará faltando um entendimento completo (especificação) do problema.

Se for apenas escolher entre um conjunto de nomes, deve ser orientado pelas convenções que você está usando para criar o sistema. Se você chegou a um novo ponto, descoberto por convenções anteriores, sempre vale a pena gastar algum esforço tentando estendê-las (de maneira adequada e consistente) para cobrir esse novo caso.

Em caso de dúvida, durma e escolha o primeiro nome mais óbvio, na manhã seguinte :-)

Se você acordar um dia e perceber que estava errado, mude imediatamente.

Paulo.

BTW: Document.fetch () é bastante óbvio.

Paul W Homer
fonte
1

Acho que tenho mais problemas nas variáveis ​​locais. Por exemplo, quero criar um objeto do tipo DocGetter. Então eu sei que é um DocGetter. Por que preciso dar outro nome a ele? Normalmente, acabo dando um nome como dg (para DocGetter) ou temp ou algo igualmente não-descritivo.

Jason Baker
fonte
1

Não se esqueça que os padrões de design (não apenas os do GoF) são uma boa maneira de fornecer um vocabulário comum e seus nomes devem ser usados ​​sempre que alguém se encaixa na situação. Isso até ajudará os recém-chegados familiarizados com a nomenclatura a entender rapidamente a arquitetura. Esta classe em que você está trabalhando deve agir como um proxy ou mesmo uma fachada?

Herrmann
fonte
1

A documentação do fornecedor não deve ser o objeto? Quero dizer, esse é tangível, e não apenas como uma antropomorfização de uma parte do seu programa. Portanto, você pode ter uma VendorDocumentationclasse com um construtor que busca as informações. Eu acho que se um nome de classe contém um verbo, muitas vezes algo deu errado.

Svante
fonte
1

Eu definitivamente sinto você. E eu sinto sua dor. Todo nome em que penso me parece um lixo. Tudo parece tão genérico e eu quero aprender a injetar um pouco de talento e criatividade em meus nomes, fazendo com que eles realmente reflitam o que descrevem.

Uma sugestão que tenho é consultar um dicionário de sinônimos. O Word é bom, assim como o Mac OS X. Isso pode realmente me ajudar a tirar a cabeça das nuvens e me dá um bom ponto de partida, além de alguma inspiração.

John Gallagher
fonte
0

Se o nome se explicasse a um programador leigo, provavelmente não há necessidade de alterá-lo.

dreamlax
fonte