Qual é a melhor abordagem para nomear classes?

92

Encontrar nomes bons e precisos para as classes é notoriamente difícil. Feito corretamente, torna o código mais autodocumentado e fornece um vocabulário para raciocinar sobre o código em um nível mais alto de abstração.

As classes que implementam um determinado padrão de projeto podem receber um nome baseado no nome do padrão bem conhecido (por exemplo, FooFactory, FooFacade), e as classes que modelam diretamente os conceitos de domínio podem receber seus nomes do domínio do problema, mas e as outras classes? Existe algo como o dicionário de sinônimos de um programador que eu possa consultar quando estiver sem inspiração e quiser evitar o uso de nomes de classe genéricos (como FooHandler, FooProcessor, FooUtils e FooManager)?

Henry
fonte
6
esta é uma excelente pergunta! Fechar é IMHO injustificado, melhor seria migrar o site dos programadores.
Timofey
1
Eu concordo, deve ser reaberto ou movido
ftl de
Tenho visto muitas dessas perguntas excelentes "fechadas por casperOne". Talvez ele pudesse servir como delecionista na Wikipedia?
Perlator

Respostas:

58

Citarei algumas passagens dos Padrões de Implementação de Kent Beck:

Nome Simples da Superclasse

"[...] Os nomes devem ser curtos e incisivos. No entanto, tornar os nomes precisos às vezes parece exigir várias palavras. Uma saída para esse dilema é escolher uma metáfora forte para o cálculo. Com uma metáfora em mente, até palavras isoladas trazem consigo uma rica teia de associações, conexões e implicações. Por exemplo, na estrutura de desenho HotDraw, meu primeiro nome para um objeto em um desenho era DrawingObject . Ward Cunningham veio junto com a metáfora da tipografia: um desenho é como uma página impressa e disposta. Os itens gráficos em uma página são figuras, então a classe se tornou Figura . No contexto da metáfora, Figura é simultaneamente mais curta, mais rica e mais precisa do que DrawingObject . "

Nome da subclasse qualificada

"Os nomes das subclasses têm duas tarefas. Eles precisam comunicar como são as classes e como são diferentes. [...] Ao contrário dos nomes nas raízes das hierarquias, os nomes das subclasses não são usados ​​com tanta frequência em conversas, para que possam ser expressivos à custa de serem concisos. [...]

Dê às subclasses que servem como raízes das hierarquias seus próprios nomes simples. Por exemplo, HotDraw tem uma classe Handle que apresenta operações de edição de figura quando uma figura é selecionada. Chama-se, simplesmente, Handle apesar de estender Figura . Há toda uma família de alças e, mais apropriadamente, têm nomes como StretchyHandle e TransparencyHandle . Como Handle é a raiz de sua própria hierarquia, ele merece um nome de superclasse simples mais do que um nome de subclasse qualificado.

Outro problema na nomenclatura de subclasses são as hierarquias de vários níveis. [...] Em vez de acrescentar cegamente os modificadores à superclasse imediata, pense no nome da perspectiva do leitor. De que classe ele precisa para saber que é essa classe? Use essa superclasse como base para o nome da subclasse. "

Interface

Dois estilos de nomear interfaces dependem de como você pensa nas interfaces. As interfaces como classes sem implementações devem ser nomeadas como se fossem classes ( nome da superclasse simples , nome da subclasse qualificada ). Um problema com esse estilo de nomenclatura é que os nomes bons são usados ​​antes de você começar a nomear classes. Uma interface chamada File precisa de uma classe de implementação chamada algo como ActualFile , ConcreteFile ou (eca!) FileImpl(um sufixo e uma abreviatura). Em geral, comunicar se se está lidando com um objeto concreto ou abstrato é importante, se o objeto abstrato é implementado como uma interface ou uma superclasse é menos importante. O adiamento da distinção entre interfaces e superclasses é bem> suportado por este estilo de nomenclatura, deixando você livre para mudar de ideia mais tarde, se necessário.

Às vezes, nomear classes concretas simplesmente é mais importante para a comunicação do que ocultar o uso de interfaces. Neste caso, prefixe os nomes das interfaces com “I”. Se a interface for chamada IFile , a classe pode ser simplesmente chamada de File .

Para uma discussão mais detalhada, compre o livro! Vale a pena! :)

Marcio aguiar
fonte
1
"Às vezes, nomear classes concretas simplesmente é mais importante para a comunicação do que ocultar o uso de interfaces. Nesse caso, prefixe os nomes das interfaces com“ I ”. Se a interface for chamada IFile, a classe pode ser simplesmente chamada de Arquivo." É tão engraçado, porque no livro Clean Code de Robert C. Martin, descobri que preferíamos nomear as implementações como FileImpl, em vez de nomear a interface como IFile, porque não queremos que o cliente saiba que estamos servindo a elas interface. E no livro ^ há citações do livro ao qual você se refere :)
Cristian Ciobotea
38

Sempre vá para MyClassA, MyClassB - permite uma boa classificação alfa.

Estou brincando!

Esta é uma boa pergunta e algo que experimentei há não muito tempo. Eu estava reorganizando minha base de código no trabalho e estava tendo problemas para saber onde colocar o quê e como chamá-lo.

O verdadeiro problema?

Eu tive aulas fazendo muito. Se você tentar aderir ao princípio de responsabilidade única, tudo ficará bem melhor. Em vez de uma classe PrintHandler monolítica , você poderia dividi-la em PageHandler , PageFormatter (e assim por diante) e, em seguida, ter uma classe principal de impressora que reúne tudo.

Na minha reorganização, demorei, mas acabei armazenando muitos códigos duplicados, tornei minha base de código muito mais lógica e aprendi muito quando se trata de pensar antes de lançar um método extra em uma classe: D

No entanto, eu não recomendaria colocar coisas como nomes de padrões no nome da classe. A interface das classes deve tornar isso óbvio (como ocultar o construtor de um singleton). Não há nada de errado com o nome genérico, se a classe estiver servindo a um propósito genérico.

Boa sorte!

Rob Cooper
fonte
Concorde em não colocar nomes de padrões no nome da classe. E se o padrão mudar posteriormente quando a implementação mudar?
thegreendroid
2
Prefiro colocar um nome ou padrão em um nome. Por quê? Porque se eu tiver que olhar os detalhes de implementação (como o construtor privado) para descobrir que é um singleton, isso está me atrasando como leitor e dependendo do meu nível de habilidade, posso não descobrir que é realmente uma parte da classe do padrão geral. Singleton e construtor privado são um exemplo questionável, mas para padrões mais complicados (Visitante, Adaptador, etc.) está ficando bem complicado. Se o padrão mudar, as chances são de que essas classes não existirão mais ...
dragan.stepanovic
28

A excelente palestra de Josh Bloch sobre um bom design de API tem alguns bons conselhos:

  • As aulas devem fazer uma coisa e fazê-lo bem.
  • Se uma classe for difícil de nomear ou explicar, provavelmente ela não está seguindo o conselho do item anterior.
  • O nome da classe deve comunicar instantaneamente o que é a classe.
  • Bons nomes geram bons designs.

Se o seu problema é como nomear classes internas expostas, talvez você deva consolidá-las em uma classe maior.

Se o seu problema é nomear uma classe que está fazendo muitas coisas diferentes, você deve considerar dividi-la em várias classes.

Se esse for um bom conselho para uma API pública, não fará mal a nenhuma outra classe.

Josh Segall
fonte
1
link de vídeo no youtube youtube.com/watch?v=aAb7hSCtvGw
Andrew Harry
12

Se você está preso a um nome, às vezes apenas dar a ele qualquer nome meio sensato com o compromisso de revisá-lo mais tarde é uma boa estratégia.

Não fique com a paralisia dos nomes. Sim, os nomes são muito importantes, mas não são importantes o suficiente para perder muito tempo com eles. Se você não consegue pensar em um bom nome em 10 minutos, siga em frente.

Simon Johnson
fonte
9

Se um bom nome não vier à mente, eu provavelmente questionaria se existe um problema mais profundo - a aula está servindo a um bom propósito? Se for, nomear deve ser bastante simples.

Luke Halliwell
fonte
3

Se o seu "FooProcessor" realmente processa foos, então não hesite em dar esse nome só porque você já tem um BarProcessor, BazProcessor, etc. Em caso de dúvida, óbvio é melhor. Os outros desenvolvedores que precisam ler seu código podem não estar usando o mesmo dicionário de sinônimos que você.

Dito isso, mais especificidade não faria mal para este exemplo particular. "Processo" é uma palavra bastante ampla. É realmente um "FooUpdateProcessor" (que pode se tornar "FooUpdater"), por exemplo? Você não precisa ser muito "criativo" quanto à nomenclatura, mas se escreveu o código, provavelmente tem uma boa ideia do que ele faz ou não.

Finalmente, lembre-se de que o nome básico da classe não é tudo o que você e os leitores do seu código precisam continuar - geralmente há namespaces em jogo também. Isso geralmente pode dar aos leitores contexto suficiente para ver claramente para que serve sua classe, mesmo que seu nome seja bastante genérico.

McKenzieG1
fonte