Existem boas técnicas ou testes para nomear tipos?

23

Uma pergunta incômoda e aberta, mas é um problema contra o qual sempre me deparo:

O software fácil de manter e trabalhar é um software bem projetado. Tentar tornar um design intuitivo significa nomear seus componentes de forma que o próximo desenvolvedor possa deduzir a função do componente. É por isso que não nomeamos nossas classes "Tipo1", "Tipo2" etc.

Quando você está modelando um conceito do mundo real (por exemplo, cliente), geralmente é tão simples quanto nomear seu tipo após o conceito do mundo real que está sendo modelado. Mas quando você está criando coisas abstratas, mais orientadas ao sistema, é muito fácil ficar sem nomes fáceis de ler e de digerir.

Fica pior (para mim) ao tentar nomear famílias de tipos, com um tipo de base ou interface que descreve o que os componentes precisam fazer, mas não como eles funcionam. Isso naturalmente leva cada tipo derivado a tentar descrever o sabor da implementação (por exemplo, IDataConnectione SqlConnectionno .NET Framework), mas como você expressa algo complicado como "funciona por reflexão e procura por um conjunto específico de atributos"?

Então, quando você finalmente escolhe um nome para o tipo que acha que descreve o que está tentando fazer, seu colega pergunta "WTF isso DomainSecurityMetadataProviderrealmente faz? "

Existem boas técnicas para escolher um nome bem-intencionado para um componente ou como construir uma família de componentes sem obter nomes confusos?

Existem testes simples que eu posso aplicar a um nome para ter uma idéia melhor se o nome é "bom" e deve ser mais intuitivo para os outros?

Paul Turner
fonte
20
seis técnicas que provaram funcionar para mim: 1) dedique muito tempo a inventar nomes 2) use as revisões de código 3) não hesite em renomear 4) gaste muito tempo a inventar nomes 5) use as revisões de código 6) não hesite em mudar o nome
gnat
5
@gnat: Por favor, poste sua resposta como resposta para que possamos votar.
precisa saber é o seguinte
3
Costumo usar um dicionário de sinônimos ao fazer novos desenvolvimentos para me ajudar a criar bons nomes.
Aprendiz do Dr. Wily
3
Eu tento evitar chamar qualquer coisa de "gerente". Alan Green e Jeff Atwood argumentam que o termo é usado em excesso e é muito vago para transmitir significado. Eu tenho que concordar.
Aprendiz do Dr. Wily

Respostas:

41

Para nomear, existem seis técnicas que comprovadamente funcionam para mim:

  1. gaste muito tempo inventando nomes
  2. usar código comentários
  3. não hesite em renomear
  4. gaste muito tempo inventando nomes
  5. usar código comentários
  6. não hesite em renomear

PS. Caso a sua API seja pública, as opções acima se aplicam antes disso, porque, você sabe,

"APIs públicas, como diamantes, são para sempre. Você tem uma chance de acertar, então dê o melhor de si ..." (Joshua Bloch, Como criar uma boa API e por que é importante )

mosquito
fonte
1
Caso seja uma API pública, existem três técnicas adicionais que você pode usar ...
UncleZeiv
1
@UncleZeiv: como ....?
FrustratedWithFormsDesigner
3
@FrustratedWithFormsDesigner: 1. gastar muito tempo em inventar nomes 2. revisões de código uso e 3. não hesite em renomear
S.Lott
3
Essa resposta me convenceu de que geralmente: não, não há uma maneira fácil de acertar os nomes. Apenas tentando trabalhos realmente difíceis.
Paul Turner
4
7. Não hesite em redesenhar tipos ou funções se for impossível criar um nome adequado para eles. Código bem projetado sempre pode ser nomeado corretamente.
Joren
8

Meu teste básico é se você pode descrever a função da variável usando apenas palavras da variável:

por exemplo, se DomainSecurityMetadataProvider "Fornece metadados de segurança de domínio" ou "Fornece metadados relacionados à segurança de domínio", é bom.

No entanto, existem nuances que variam de pessoa para pessoa:

por exemplo, para mim, original_team_code é o código para a equipe original, enquanto para outra pessoa pode ser o código original para a equipe. Meu favorito pessoal era "UnsafeLegacyMutex", que não pude deixar de ler como "Este é um Mutex Legado que não é Seguro", em vez de "Este é um Mutex para o Código Legado ThreadUnsafe".

Portanto, meu teste estendido é escrever a variável em um fórum / wiki / chat e fazer com que as pessoas adivinhem o que isso significa.

Deworde
fonte
7

Existem boas técnicas para escolher um nome bem-intencionado para um componente ou como construir uma família de componentes sem obter nomes confusos?

Na verdade não.

Uma dica, no entanto, é evitar a "voz passiva".

"DomainSecurityMetadataProvider" é passivo. Não há verbo, são todos os substantivos e substantivos usados ​​como adjetivos.

"ProvideMetadataForDomainSecurity" é mais ativo. Há um verbo.

A programação orientada a objetos é todo (realmente) substantivo-verbo. Substantivo == objeto. Verbo == método. Portanto, um nome de classe geralmente é muito "substantivo". Quebrar esse hábito e começar a inserir verbos é difícil.

Existem testes simples que eu posso aplicar a um nome para ter uma idéia melhor se o nome é "bom" e deve ser mais intuitivo para os outros?

Sim. Você definiu um excelente teste em sua pergunta. Pergunte a outras pessoas.

Antigamente, chamamos isso de "passo a passo do design". Foi um grande negócio suado em uma metodologia em cascata. Atualmente, com os métodos Agile, deve ser uma colaboração comum entre o autor e os usuários de uma classe. Não demora (e não deve) demorar muito. Discutir o design (e os nomes) antes de escrever os testes (e o código) reduzirá o fator de espanto e pode impedir os WTFs.

S.Lott
fonte
12
Não tenho certeza se concordo com a ideia de voz passiva. Para mim, as aulas fazem mais sentido como substantivos.
deworde
7
De um modo geral, estou tentando manter meus nomes de tipo em voz passiva, pois combina com o estilo de verbo substantivo de OOP. Eu consideraria ProvideMetadataForDomainSecurityum nome de tipo ruim. Os nomes dos métodos geralmente são muito mais fáceis de nomear com precisão, porque sou livre para usar verbos. A restrição de linguagem é o cerne do problema.
Paul Turner
Por mais que eu goste de "perguntar às pessoas" como um teste real, devo perguntar aos meus colegas sobre como nomear pelo menos duas vezes por dia. Espero algo que não exija o tempo de outras pessoas.
Paul Turner
2
Classes fazer faz sentido como substantivos. O problema são essas classes complexas com frases longas de adjetivo de substantivo. Preposições podem ajudar também.
S.Lott
2
A colaboração é o segredo de um bom software. A colaboração leva tempo. Não há caminho real para uma boa escrita.
S.Lott
6

Usando um dicionário de sinônimos

Muitas vezes vou me referir a um dicionário de sinônimos ao fazer um novo desenvolvimento, a fim de encontrar palavras apropriadas para descrever minhas classes e métodos.

Classes que contêm principalmente lógica de operação

Costumo nomear classes que fornecem principalmente métodos de operação em uma estrutura de verbo substantivo, como "EntityProvider", "EntityLocator" etc.

Essas classes geralmente não contêm muito estado.

Classes que contêm estado

As telas da interface do usuário e as entidades de dados geralmente são com estado e, portanto, eu simplesmente nomeio essas classes com um padrão substantivo ou adjetivo-substantivo.

Exemplos: Person, Employee, CurrentEmployee, FormerEmployee

Classes de utilidade

As classes que contêm apenas métodos estáticos são geralmente consideradas classes "utilitárias", portanto, eu as nomeio consistentemente com o sufixo "Utilitário".

Exemplos: NetworkUtilities, FileUtilities

Testes

Não tenho bons testes para decidir se algo é mal nomeado, mas sugiro que tente usar um único substantivo e / ou um verbo único no nome e depois pense se esse substantivo / verbo descreve com precisão o que você ' renomear.

Se você achar que há mais na classe / método que não é capturado pelo nome, talvez essa classe / método precise ser refatorada.

Alan Green e Jeff Attwood escreveram sobre os males das classes de nomes com o sufixo "Manager". Eles argumentam que o termo "gerente" é usado em excesso e é muito vago para transmitir algo significativo. Eu tenho que concordar.

O artigo de Jeff também fornece uma lista de diretrizes sugeridas no Code Complete de Steve McConnell.

variáveis

Recentemente, experimentei nomes de variáveis ​​/ parâmetros descritivos mais longos que incorporam preposições, como "Of", "By", "For" etc. Alguns exemplos são mostrados abaixo:

string firstNameOfEmployee;

string lastNameOfEmployee;

// here I nimbly avoid worrying about whether to call it "Id" or "ID" :)
int idOfEmployee;

decimal amountForDeposit;

Account accountForDeposit;

Acho que isso funciona bem com o recurso intellisense do Visual Studio, facilitando a digitação desses nomes longos. Também acho que há menos duplicação de prefixos de nomes de variáveis ​​(por exemplo, personID, personFirstName, personLastName vs. idOfPerson, firstNameOfPerson, lastNameOfPerson), fornecendo um "hash" melhor que torna o intellisense ainda mais útil.

Aprendiz do Dr. Wily
fonte
1
Vou enfatizar o assunto sobre nomes de variáveis ​​longas, mais uma vez, o Visual Studio (se você estiver usando) torna isso um acéfalo. É muito menos prejudicial ter nomes de variáveis ​​longos que são explícitos do que nomes de variáveis ​​curtos, nos quais é necessário "pensar" ou investigar o que o nome realmente significa. Pense também no contexto. Prefiro ver "peopleToDelete" do que "listOfPeople". Novamente, o Visual Studio informa o tipo da variável, sem a necessidade de incluí-la.
precisa saber é o seguinte
Também não gosto da notação húngara elaborada que você adicionou aos nomes de variáveis. Eu não precisaria me importar se uma coleção de identificações de pessoa é uma List, matriz IEnumerableou ConcurrentQueue. É necessário enumerar vários IDs, e os detalhes de implementação de como eles são armazenados são bagagem mental desnecessária. Embora eu concorde geralmente que, se um nome mais longo for consideravelmente mais descritivo, ele deve ser preferido em vez de um nome mais curto e menos claro.
Allon Guralnek
@ Allon - Engraçado, eu estava prestes a revisar minha resposta com base no comentário de SkippyFire. Na verdade, eu concordo com você; meu exemplo cheira a notação húngara. Minha única defesa é que é fácil ler o código e entender os tipos de dados envolvidos sem um IDE disponível, como se eu estivesse lendo um diff de controle de origem. Isso não é desculpa, no entanto. :) Vou revisar meu exemplo para estar de acordo com firstNameOfEmployee, lastNameOfEmployee, etc.
Dr. Wily's Apprentice
2

Então, quando você finalmente escolhe um nome para o tipo que você acha que descreve o que está tentando fazer, seu colega pergunta "WTF esse DomainSecurityMetadataProvider realmente faz?"

Que tipo de nome você espera para uma classe complexa e específica de domínio? Isso é tão bom quanto é possível sem tornar o nome da classe uma sentença (o que fará todo mundo pensar que você deu muita responsabilidade a uma única classe)

Eu consideraria retirar o provedor do nome. Se mencionar especificamente metadados, todo mundo já sabe que você está usando reflexão. Você pode torná-la uma palavra mais concisa (ou possivelmente mudar para outra palavra - é mais um consumidor do que um provedor do que você escreveu)

Brian
fonte
Os metadados em questão não são derivados da reflexão (mas descrevem como tratar tipos). O tipo implementa uma ISecurityMetadataProviderinterface, que existe em um ponto injetável na infraestrutura de segurança, para fornecer informações ao subsistema. Nomear é difícil.
Paul Turner
Considero DomainSecurityMetadataProviderser um provedor de DomainSecurityMetadataobjeto, onde DomainSecurityMetadataestão os próprios metadados. Nome claro e compreensível. Eu nem preciso saber o que DomainSecurityMetadataé! É apenas um objeto que esse provedor fornece. Apenas remover um Providersufixo não melhora a legibilidade, mas muito pelo contrário - reduza-o. Sem esse sufixo, acho que são apenas alguns metadados (objeto de contêiner para alguns metadados), mas não um objeto para obter metadados de (um provedor).
Ruslan Stelmachenko 25/02
0

Use metáforas para descrever partes do sistema. Não apenas fará com que você descubra novas analogias, como ajudará a nomear mais facilmente.

(Sei que esse não é um exemplo forte, mas de qualquer maneira). Por exemplo, você pode chamar uma variável ou um tipo como mailbox, que serve como uma fila para as mensagens recebidas de uma classe.

nimcap
fonte
-1

Uma coisa em que eu seria muito firme é que NUNCA deve ser permitido que os Nomes estejam incorretos. O melhor exemplo, durante algumas re-fatorações, muito código foi alterado e algumas variáveis ​​começaram a se referir a algo diferente do que seus nomes sugeriam.

Muito em breve, um programador estava gastando idades e usando algumas chamadas de banco de dados muito caras, tentando obter certos dados que já haviam sido extraídos e armazenados. Renomeei tudo e, de repente, conseguimos remover uma tonelada de lógica complicada e com bugs.

Deworde
fonte
1
você deve excluir esta resposta e editar em sua resposta originação
Ryathal
Penso que esta é uma resposta diferente da minha outra resposta.
deworde
-1

Felizmente, casos em que você tem que pensar tanto sobre os nomes são raros. Quando esses casos surgirem, basta escrever um parágrafo explicando o que a classe faz. Ao contrário dos comentários em função ou do nível de função, o objetivo principal de uma classe raramente muda, portanto o risco de comentários ficarem desatualizados é relativamente pequeno. Então, você pode escrever alguns parágrafos ou desenhar ASCII para explicar o que a classe faz.

kizzx2
fonte