Nomeando Classes - Como evitar chamar tudo de um "Gerenciador de <Qualquer>"? [fechadas]

1188

Há muito tempo, li um artigo (acredito que seja uma entrada de blog) que me colocou no caminho "certo" para nomear objetos: Seja muito cuidadoso ao nomear coisas em seu programa.

Por exemplo, se meu aplicativo fosse (como um aplicativo comercial típico) manipulando usuários, empresas e endereços, eu teria uma classe a User, a Companye Addressdomain - e provavelmente em algum lugar a UserManager, a CompanyManagere a AddressManagerapareceriam e tratariam dessas coisas.

Então você pode dizer que aqueles UserManager, CompanyManagere AddressManagerfazer? Não, porque Manager é um termo muito genérico que se ajusta a qualquer coisa que você possa fazer com seus objetos de domínio.

O artigo que li recomendou o uso de nomes muito específicos. Se fosse um aplicativo C ++ e o UserManagertrabalho do usuário estivesse alocando e liberando usuários da pilha, ele não gerenciaria os usuários, mas protegeria seu nascimento e morte. Hmm, talvez possamos chamar isso de UserShepherd.

Ou talvez o UserManagertrabalho do examinador seja examinar os dados de cada objeto Usuário e assinar os dados criptograficamente. Então nós teríamos um UserRecordsClerk.

Agora que essa ideia ficou comigo, tento aplicá-la. E ache essa ideia simples incrivelmente difícil.

Posso descrever o que as classes fazem e (desde que eu não caia na codificação rápida e suja) as classes que escrevo fazem exatamente uma coisa. O que sinto falta de passar dessa descrição para os nomes é um tipo de catálogo de nomes, um vocabulário que mapeia os conceitos para nomes.

Por fim, gostaria de ter algo como um catálogo de padrões em minha mente (freqüentemente os padrões de design fornecem facilmente os nomes dos objetos, por exemplo, uma fábrica )

  • Fábrica - Cria outros objetos (nomeação tirada do padrão de design)
  • Pastor - Um pastor lida com a vida útil dos objetos, sua criação e desligamento
  • Sincronizador - copia dados entre dois ou mais objetos (ou hierarquias de objetos)
  • Babá - Ajuda os objetos a atingir o estado "utilizável" após a criação - por exemplo, conectando outros objetos

  • etc etc.

Então, como você lida com esse problema? Você tem um vocabulário fixo, inventa novos nomes rapidamente ou considera nomear coisas não tão importantes ou erradas?

PS: Também estou interessado em links para artigos e blogs que discutem o assunto. Para começar, aqui está o artigo original que me fez pensar sobre isso: Nomeando classes Java sem um 'gerente'


Atualização: Resumo das respostas

Aqui está um pequeno resumo do que aprendi com essa pergunta enquanto isso.

  • Tente não criar novas metáforas (babá)
  • Veja o que outras estruturas fazem

Mais artigos / livros sobre este tópico:

E uma lista atual de prefixos / sufixos de nomes que eu coletei (subjetivamente!) Das respostas:

  • Coordenador
  • Construtor
  • Escritor
  • Leitor
  • Handler
  • Recipiente
  • Protocolo
  • Alvo
  • Conversor
  • Controlador
  • Visão
  • Fábrica
  • Entidade
  • Balde

E uma boa dica para a estrada:

Não fique com paralisia de nomes. Sim, os nomes são muito importantes, mas não são importantes o suficiente para desperdiçar grandes quantidades de tempo. Se você não conseguir encontrar um bom nome em 10 minutos, siga em frente.

froh42
fonte
11
Ele pertence ao wiki da comunidade porque não há uma resposta "melhor". É uma discussão.
DOK
13
Isso é contra-intuitivo. Eles não deveriam chamar isso de fórum? Eu acho que um wiki seria para uma coleção de fatos, não opiniões.
21413 AaronLS
78
Obrigado por manter isso atualizado - mas ugh, essa última dica é um péssimo conselho! Se você não consegue pensar em um bom nome em 10 minutos, provavelmente há algo errado com sua classe. (Com as ressalvas padrão: 1) perfeito é inimigo do bom, 2) O transporte marítimo é um recurso - basta lembrar que você está incorrer em dívida técnica).
Jeff Sternal
11
Se você não conseguir encontrar um bom nome em 10 minutos, peça ajuda ao seu colega. Não desista.
9
Se você não conseguir encontrar um bom nome em 10 minutos, tente explicá-lo aos seus colegas; eles podem pensar em um bom nome (usuário338195), mas tentar explicá-lo provavelmente o ajudará a descobrir o que há de errado com ele ( Jeff ).
WillC

Respostas:

204

Fiz uma pergunta semelhante , mas sempre que possível, tento copiar os nomes que já estão na estrutura .NET e procuro idéias nas estruturas Java e Android .

Parece Helper, Managere Utilsão os substantivos inevitáveis anexados pela coordenação classes que contêm nenhum estado e são geralmente processual e estático. Uma alternativa é Coordinator.

Você poderia começar prosey particularmente roxo com os nomes e ir para coisas como Minder, Overseer, Supervisor, Administrator, e Master, mas como eu disse eu prefiro mantê-lo como os nomes quadro que você está acostumado.


Alguns outros sufixos comuns (se esse for o termo correto) que você também encontra na estrutura .NET são:

  • Builder
  • Writer
  • Reader
  • Handler
  • Container
Chris S
fonte
4
Eu gosto muito disso. Eles não caem na armadilha de metáforas ruins ou desconhecidas porque já estão sendo usadas pelo .NET Framework. Pode ser interessante consultar outras bibliotecas (Java) também para obter mais informações sobre o que é comumente usado.
precisa saber é o seguinte
Eu gostaria de sugerir Conductor, como o maestro de uma orquestra musical. É certamente um papel importante, dependendo da natureza das colaborações que você precisa "conduzir" (outros objetos são atores muito especializados que devem responder ao comando centralizado e não se preocupam muito com todos os outros colaboradores).
Heltonbiker
1
Não acredito que a solução para -er classes seja criar um nome diferente. Como li em muitos outros posts e estou tentando aprender a resposta, é que você precisa alterar a arquitetura, não apenas o nome usado.
Michael Ozeryansky 03/11/19
115

Você pode dar uma olhada em source-code-wordle.de , analisei lá os sufixos mais usados ​​dos nomes de classe do .NET framework e algumas outras bibliotecas.

Os 20 principais são:

  • atributo
  • tipo
  • ajudante
  • coleção
  • conversor
  • manipulador
  • informação
  • fornecedor
  • exceção
  • serviço
  • elemento
  • Gerente
  • opção
  • fábrica
  • contexto
  • item
  • desenhador
  • base
  • editor
Markus Meyer
fonte
147
Em uma empresa em particular, há muito tempo, eu conhecia um engenheiro tão farto da absurda e crescente infinidade de regras de sufixo que assolavam a empresa que desafiadoramente terminava todas as aulas Thingy.
8
Essa lista de nomes por si só não é tão útil sem o contexto do qual o sufixo deve ser aplicado.
Fred
65

Sou a favor de bons nomes e costumo escrever sobre a importância de tomar muito cuidado ao escolher nomes para as coisas. Por essa mesma razão, desconfio de metáforas ao nomear coisas. Na pergunta original, "fábrica" ​​e "sincronizador" parecem bons nomes para o que parecem significar. No entanto, "pastor" e "babá" não são, porque são baseados em metáforas . Uma classe no seu código não pode ser literalmente uma babá; você chama isso de babá porque cuida de outras coisas, da mesma forma que uma babá da vida real cuida de bebês ou crianças. Isso é bom no discurso informal, mas não é bom (na minha opinião) para nomear classes no código que terá que ser mantido por quem sabe quem sabe quando.

Por quê? Porque as metáforas são dependentes da cultura e muitas vezes dependem também do indivíduo. Para você, nomear uma classe como "babá" pode ser muito claro, mas talvez não seja tão claro para outra pessoa. Não devemos confiar nisso, a menos que você esteja escrevendo um código apenas para uso pessoal.

Em qualquer caso, a convenção pode criar ou quebrar uma metáfora. O uso de "factory" em si é baseado em uma metáfora, mas que existe há algum tempo e atualmente é bastante conhecida no mundo da programação, então eu diria que é seguro usá-lo. No entanto, "babá" e "pastor" são inaceitáveis.

CesarGon
fonte
10
Esse argumento realmente se desdobra em que obviamente a própria fábrica é uma metáfora. Muitas vezes, as metáforas realmente esclarecem o que um objeto pode ser bom, enquanto ser vago ou genérico garante automaticamente que a única maneira de descobrir o que o código faz é lendo-o completamente! O pior cenário possível.
Kzqai #
1
+1 por evitar nomes "fofos". Eu acho ótimo ser o mais direto possível com a linguagem. (É claro que nem sempre é fácil ser direto, sucinto, precisa e inequívoca, tudo ao mesmo tempo ...)
andrewf
1
Uma escolha inventiva do verbo + "er" geralmente será mais clara para as classes concretas do que uma analogia colorida. Novas abstrações, por outro lado - coisas que são um novo conceito, um novo "tipo de coisa" em vez de apenas uma nova "coisa" - geralmente funcionam bem como metáforas ("beans" de Java, "lentes" de Haskell, GUI) "windows", "promessas" de muitos idiomas). A maioria das bases de código não possui invenções genuínas como essa.
Malnormalulo
51

Nós poderíamos fazer sem qualquer xxxFactory, xxxManagerou xxxRepositoryaulas se modelou o mundo real corretamente:

Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
        .Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
        .OfType<User>().CreateNew("John Doe");

;-)

herzmeister
fonte
11
Como você chegaria a universos paralelos e dimensões alternativas?
tster
23
Isso é fácil: Omniverse.Instance.Dimensions ["Nossos"]. Universos ["Nossos"]. Galáxias ... ... ok, ok, admito que isso exigiria uma recompilação. ;-)
herzmeister 15/01
73
Atualização: isso foi adicionado no .NET 4.0 Universe.Instance.ToParallel()
:;
2
Quebra a lei de Demeter!
Jonas G. Drange
13
Esses são objetos e membros, e não nomes de classe
Harry Berry
39

Parece uma ladeira escorregadia para algo publicado em thedailywtf.com, "ManagerOfPeopleWhoHaveMortgages" etc.

Suponho que é certo que uma classe monolítica do Manager não seja um bom design, mas usar 'Manager' não é ruim. Em vez do UserManager, podemos dividi-lo em UserAccountManager, UserProfileManager, UserSecurityManager, etc.

'Gerente' é uma boa palavra porque mostra claramente que uma classe não está representando uma 'coisa' do mundo real. 'AccountsClerk' - como devo saber se é uma classe que gerencia os dados do usuário ou representa alguém que é um funcionário de contabilidade para o seu trabalho?

Mr. Boy
fonte
8
E o UserAccounter, UserProfiler e UserSecurer? Se você se livrar do Manager, será forçado a apresentar uma definição específica, o que eu acho uma coisa boa.
Didier A.
10
E sobre UserAccount, UserProfile, UserSecurity oO?
clime
3
Eu o chamaria de "MortageOwnersManager"
volter9
Às vezes, o domínio tem nomes específicos. Como "MortageHolder" que pode ser melhor que "MortageOwner"
borjab
24

Quando me pego pensando em usar Managerou Helperem um nome de classe, considero um cheiro de código que significa que ainda não encontrei a abstração correta e / ou estou violando o princípio da responsabilidade única , refatorando e colocando mais esforço no design geralmente facilita muito a nomeação.

Mas mesmo as classes bem projetadas não (sempre) se autodenominam, e suas escolhas dependem em parte de você estar criando classes de modelo de negócios ou classes de infraestrutura técnica.

As classes de modelo de negócios podem ser difíceis, porque são diferentes para cada domínio. Existem alguns termos que eu uso muito, como Policypara classes de estratégia em um domínio (por exemplo, LateRentalPolicy), mas eles geralmente fluem da tentativa de criar uma " linguagem onipresente " que você pode compartilhar com os usuários de negócios, projetando e nomeando classes para que elas modelem real idéias, objetos, ações e eventos do mundo.

As classes de infraestrutura técnica são um pouco mais fáceis, porque descrevem domínios que conhecemos muito bem. Prefiro incorporar nomes de padrões de design nos nomes de classe, como InsertUserCommand, CustomerRepository,ou SapAdapter.entendo a preocupação em comunicar a implementação em vez de intenção, mas os padrões de design combinam esses dois aspectos do design de classe - pelo menos quando você está lidando com infraestrutura, onde deseja o design da implementação seja transparente, mesmo enquanto você oculta os detalhes.

Jeff Sternal
fonte
1
Eu realmente gosto da idéia de usar o Policysufixo para as classes que contêm lógica de negócios
jtate
+1 por mencionar o cheiro do código associado a nomes como "Gerente" e "Auxiliar". Descobri que, se não tenho nomes claros para as coisas, geralmente isso decorre, pelo menos em parte, de alguma imprecisão no meu entendimento do domínio, seja comercial ou técnico. Quase de maneira equivalente, isso pode significar que estou apenas dividindo reativamente as classes porque elas "ficaram grandes demais" - o que para mim também é um sinal de modelagem inadequada. Essa deve ser a resposta mais votada.
Nclark 28/12/19
10

Estar em conformidade com os padrões definidos pelo (digamos) livro do GOF e nomear objetos depois deles me ajudam bastante a nomear classes, organizá-las e comunicar a intenção. A maioria das pessoas entenderá essa nomenclatura (ou pelo menos uma parte importante).

Brian Agnew
fonte
Fowler é uma boa referência para mim, mas o GOF é uma ótima recomendação.
Lazarus
Perdoe minha ignorância. A que livro Fowler você está se referindo?
Brian Agnew
19
Hmm, às vezes isso funciona (por exemplo, como uma fábrica ou uma estratégia), mas outras vezes sinto que isso comunica a maneira de implementação (usei um padrão!) Mais do que a intenção e o trabalho da classe. Por exemplo, a coisa mais importante de um Singleton é o que ele representa - e não que seja um Singleton. Assim, nomear estritamente os padrões usados ​​é como nomear estritamente os tipos usados. Por exemplo notação húngara como mis-aplicados pelo grupo Sistemas Windows (descrevendo o tipo de dados C em vez de "tipo intenção")
froh42
1
Para classes de infraestrutura técnica, geralmente é desejável tornar a implementação transparente - e a maioria dos nomes de padrões de design canônicos comunica a implementação e a intenção. Classes de modelo de domínio são outra questão, no entanto.
Jeff Sternal
10

Se eu não conseguir criar um nome mais concreto para minha classe do que o XyzManager, seria um ponto para eu reconsiderar se essa é realmente uma funcionalidade que pertence à classe, ou seja, um 'cheiro de código' arquitetônico.

Jasper van den Bosch
fonte
8

Penso que o mais importante a ter em mente é: o nome é descritivo o suficiente? Você pode dizer olhando para o nome o que a classe deve fazer? O uso de palavras como "Gerente", "Serviço" ou "Manipulador" em seus nomes de classe pode ser considerado muito genérico, mas, como muitos programadores as utilizam, isso também ajuda a entender para que serve a classe.

Eu mesmo tenho usado muito o padrão de fachada (pelo menos, acho que é assim que é chamado). Eu poderia ter uma Userclasse que descreva apenas um usuário e uma Usersclasse que rastreie minha "coleção de usuários". Não chamo a turma de a UserManagerporque não gosto de gerentes na vida real e não quero ser lembrado deles :) O simples uso da forma plural me ajuda a entender o que a turma faz.

Droozle
fonte
Também gosto muito dessa abordagem, porque facilita a idéia de gerenciamento de cima para baixo de objetos. É provável que um grupo de usuários implique que o trabalho seja realizado entre usuários, e não no UserManager inativo. Além disso, ter um Usuário com uma referência a Usuários não parece tão estranho quanto possuir o UserManager. É mais aberto ao pensamento relativo, em vez de estritamente OOP.
Seph Reed
O problema dessa abordagem é que fica muito difícil pesquisar seu código Users, especialmente se você passar o objeto gerenciador. this.users = new Users()Mas, invariavelmente, em algum outro lugar do seu código usersse referirá a uma matriz de Users.
Snowman
Como você diz, Usuários de fato implica uma "coleção de usuários" - uma coleção de entidades com estado. Mas o SRP significa que você não gostaria de agrupar o gerenciamento de usuários (funcionalidade e lógica de negócios) com dados do usuário (estado). Não dizendo que você está errado, apenas que o UserManager é apropriado se a classe for responsável por gerenciar usuários e não apenas armazenar seu estado e CRUD básico.
Richard Moore
5

Específico ao C #, achei que "Diretrizes de design da estrutura: convenções, idiomas e padrões para bibliotecas .NET reutilizáveis" tinham muitas informações boas sobre a lógica da nomeação.

No entanto, quanto a encontrar essas palavras mais específicas, geralmente uso um dicionário de sinônimos e pulo as palavras relacionadas para tentar encontrar uma boa. No entanto, tento não passar muito tempo com ele, à medida que progrido no desenvolvimento, encontro nomes melhores, ou às vezes percebo que isso SuchAndSuchManagerrealmente deve ser dividido em várias classes, e então o nome dessa classe obsoleta se torna um problema. .

AaronLS
fonte
3

Acredito que o importante aqui é ser consistente dentro da esfera de visibilidade do seu código, ou seja, desde que todos que precisam olhar / trabalhar no seu código entendam sua convenção de nomenclatura, tudo bem, mesmo se você decidir chamá-lo 'CompanyThingamabob' e 'UserDoohickey'. A primeira parada, se você trabalha para uma empresa, é verificar se há uma convenção de empresa para nomear. Se não houver ou você não trabalha para uma empresa, crie seus próprios termos que fazem sentido para você, passe-o para alguns colegas / amigos de confiança que pelo menos codificam casualmente e incorpore qualquer comentário que faça sentido.

Aplicar a convenção de outra pessoa, mesmo que seja amplamente aceito, se ela não sair da página, é um erro no meu livro. Antes de tudo, preciso entender meu código sem fazer referência a outra documentação, mas ao mesmo tempo precisa ser genérico o suficiente para que não seja incompreensível para outra pessoa no mesmo campo do mesmo setor.

Lázaro
fonte
1
Ainda assim, uma convenção consistente, embora pouco intuitiva, é melhor do que apenas iniciar sua própria convenção. As pessoas que trabalham em um projeto aprenderão rapidamente qualquer convenção consistente e logo esquecerão que a funcionalidade não é exatamente o que seria esperado à primeira vista.
Mr. Boy
@ John, foi exatamente o que eu disse. A convenção precisa ser aceita pelo grupo e, se você estiver trabalhando em uma empresa, verifique se há uma convenção da empresa. Para a empresa que estou pensando em qualquer grupo, seja uma equipe de projeto de código aberto ou uma coleção solta de programadores. Se todo mundo pegasse o que estava disponível que quase se encaixasse em seus requisitos, acho que teríamos muita falta de inovação.
Lázaro
2

Eu consideraria os padrões que você está usando para o seu sistema, as convenções de nomenclatura / catalogação / agrupamento de classes de tendem a ser definidas pelo padrão usado. Pessoalmente, apego a essas convenções de nomenclatura, pois elas são a maneira mais provável de outra pessoa conseguir pegar meu código e executá-lo.

Por exemplo, UserRecordsClerk pode ser melhor explicado como estendendo uma interface RecordsClerk genérica que UserRecordsClerk e CompanyRecordsClerk implementam e depois se especializam, o que significa que é possível olhar para os métodos na interface para ver para que geralmente são as subclasses.

Veja um livro como Design Patterns para obter informações, é um excelente livro e pode ajudá-lo a esclarecer onde você deseja estar com seu código - se você ainda não o estiver usando! ; o)

Acho que, desde que seu padrão seja bem escolhido e usado na medida do apropriado, nomes de classes simples e pouco convidativos devem ser suficientes!

Caroline
fonte
Eu comentei isso na resposta de Brian Agnew. Não sinto que os nomes dos padrões sejam bons nomes de classe apenas em alguns casos (Fábrica, Estratégia), mas não em outros (Singleton). Quero que os nomes reflitam o trabalho da classe e não a maneira como eu o implementei.
Froh42