Peguei o termo smurf nomeando daqui (número 21). Para salvar alguém que não conhece o problema, a nomeação Smurf é o ato de prefixar um monte de classes, variáveis etc. relacionadas com um prefixo comum, para que você acabe com "a SmurfAccountView
passa a SmurfAccountDTO
para SmurfAccountController
", etc.
A solução que geralmente ouvi sobre isso é criar um espaço para nome de smurf e soltar os prefixos de smurf. Isso geralmente me serviu bem, mas estou com dois problemas.
Estou trabalhando com uma biblioteca com uma
Configuration
classe. Poderia ter sido chamado,WartmongerConfiguration
mas está no espaço de nomes do Wartmonger, por isso é chamadoConfiguration
. Da mesma forma, tenho umaConfiguration
classe que poderia ser chamadaSmurfConfiguration
, mas é no espaço para nome Smurf, portanto seria redundante. Há lugares no meu código em queSmurf.Configuration
aparece ao ladoWartmonger.Configuration
e digitar nomes totalmente qualificados é desajeitado e torna o código menos legível. Seria melhor lidar com aeSmurfConfiguration
(se fosse meu código e não uma biblioteca)WartmongerConfiguration
.Eu tenho uma classe chamada
Service
no meu namespace Smurf que poderia ter sido chamadaSmurfService
.Service
é uma fachada no topo de uma complexa biblioteca Smurf que executa tarefas Smurf.SmurfService
parece um nome melhor, porqueService
sem o prefixo Smurf é incrivelmente genérico. Eu posso aceitar queSmurfService
já era um nome genérico, inútil, e tirar smurf apenas tornou isso mais aparente. Mas poderia ter sido nomeadoRunner
,Launcher
etc, e ainda me "sentiria melhor" comoSmurfLauncher
porque não sei o queLauncher
faz, mas sei o queSmurfLauncher
faz. Você poderia argumentar que o que umSmurf.Launcher
faz deve ser tão aparente quanto umSmurf.SmurfLauncher
, mas eu pude ver o `Smurf.Launcher sendo algum tipo de classe relacionada à instalação, em vez de uma classe que lança smurfs.
Se houver uma maneira aberta e fechada de lidar com qualquer uma dessas opções, isso seria ótimo. Caso contrário, quais são algumas práticas comuns para atenuar seu aborrecimento?
fonte
Smurf.Launcher
Smurfs lançamento, ou ele lançarSmurfJob
s? Talvez pudesse ser chamadoSmurf.JobLauncher
?SmurfJob
ou executa tecnicamente para ser consistente com o idioma da documentação do Smurf. À luz disso e das outras respostas, vou mudar o nomeSmurfService
paraSmurfJobRunner
. Parece que o número 1 não possui uma melhor resolução independente de idioma, como eu esperava. Eu posso ver casos em que irSmurfConfiguration
seria a decisão certa, mas no meu caso, acho queConfiguration
é melhor mesmo com o incômodo deWartmonger.Configuration
.Smurf.Configuration
e seSmurfConfiguration
sentir diferente? Certamente não é o char extra, é? (Reduza paraConfig
se o comprimento é o problema.)Smurf.Configuration
Há algum problema queSmurfConfiguration
não existe?Respostas:
Você levanta alguns bons pontos.
No que diz respeito a ter classes duplicadas, você pode alternar as classes em C #. Use por exemplo
using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
Veja esta postagem no StackOverflow . Você não indicou sua linguagem de programação, mas deduzi-a do que escreveu. Portanto, onde você lida com dois projetos diferentes, é possível aliasá-los comoSmurfConfiguration
eWartmongerConfiguration
que liberariam ambiguidade ao consumir as duas classes.Como um serviço é exposto a aplicativos externos, não vejo problema em marcar o serviço com o nome do seu aplicativo, portanto, nesse caso,
SmurfService
seria válido, pois desambiguaria grupos de serviços no aplicativo consumidor.Sinto que os namespaces devem ser usados para evitar esse estilo de nomeação. Isso torna mais difícil o grok do código e ver o valor nominal de uma classe sem ler MyCompanyMyProductMyAreaClassName. O uso da técnica de aliasing permite reduzir a ambiguidade quando necessário. A única vez em que acho que você deve introduzir complexidade em sua nomeação é, como mostrei no item 2, quando as pessoas estarão consumindo um serviço. É aqui que faz todo o sentido ter esse estilo de nomeação, porque se o consumidor tiver uma variedade de serviços, ele estará consumindo a ambiguidade que pode ser confusa.
fonte
org.apache.smurfville.wartmonger.configuration
. Infelizmente, isso exclui aliases. 2 é um ponto sólido, por isso vou manter a marca Smurf para o Serviço.O objetivo dos espaços para nome é que você possa ter classes com o mesmo nome de diferentes bibliotecas sem que elas colidam. Quando você precisar usar a mesma classe nomeada de ambos, precisará remover a ambiguidade prefixando uma ou ambas com seu escopo de espaço para nome.
Dito isto, não é tão ruim ter um monte de aulas de Smurf se o Smurf lhe disser algo específico sobre a classe. Os nomes das classes devem ser descritivos o suficiente para fornecer algumas informações sobre o que a classe faz.
Da mesma forma, um
DBSession
pode pegar umDBRequest
objeto que retorna umDBResponse
objeto. OHttpSession
poder também operam emHttpRequest
eHttpResponse
objetos.Estas são aulas de Smurf com um propósito.
Eles podem viver no
MyCompany
espaço de nomes, masMyCompanyHttpSession
eMyCompanyDBSession
não dar-lhe mais alguma informação que você tinha antes. Nesse caso, solte o Smurf e faça dele um espaço para nome.fonte
Eu já enfrentei esse mesmo ponto de confusão antes e geralmente é realmente uma questão de incluirmos o tipo de coisa que faz parte do nome.
Você menciona
SmurfConfiguration
eWartmongerConfiguration
como possíveis tipos de configurações. Você indica que removeu o adjetivo (seu tipo) em seu espaço para nome, de modo que o que resta é apenas a baunilhaConfiguration
. Eu evitaria fazer isso.É como decidir que sorvete de morango é apenas sorvete no espaço para nome de morango e da mesma forma com chocolate, mas o que aconteceu é que você se divorciou do adjetivo que lhe dá identidade da coisa em si. Não é sorvete na categoria de morango. É sorvete de morango - um tipo de sorvete.
Vamos imaginar que, no seu aplicativo, você importe a
Strawberry.IceCream
classe e comece a instanciar diretamenteIceCream
.Isso pode parecer bom e bom, até o momento em que você acaba importando outra
IceCream
aula. Agora você está de volta ao problema original de ter que, de alguma forma, distinguir entre eles, o que é problemático. O que você queria o tempo todo era:É melhor deixar espaços de nome para evitar possíveis conflitos entre terceiros que possam representar incidentalmente os mesmos conceitos em suas bibliotecas. Quando um desenvolvedor cria uma biblioteca ou projeto, no entanto, ele deve nomear cada conceito exclusivamente e usar espaços de nome como pastas apenas para organização. Muitas vezes, o nome da pasta é encontrado no nome dos conceitos que ela organiza e tudo bem.
fonte
Definitivamente, é uma boa regra geral que, se você tiver um prefixo comum em várias classes, provavelmente eles merecem entrar em seu próprio espaço de nome. Para lidar com o problema, então, quando você precisar usar classes nomeadas de maneira semelhante em dois namespaces:
1) Alias os namespaces, embora eu o abrevie e seja direto, qualquer abreviação natural, talvez até apenas uma letra:
Em seguida, sempre prefixe onde quer que seja usado e nomeie as instâncias adequadamente:
2) Alias da turma, conforme sugerido em outra resposta.
3) Qualquer biblioteca que você tem controle, considere não usar o termo 'Configuração'. Use o dicionário de sinônimos: por exemplo, 'Configurações', 'Modelo', 'Parâmetros'. De qualquer maneira, pode ser mais significativo para o contexto: por exemplo, se o Smurf fosse algum tipo de módulo de análise numérica que você tivesse escrito, talvez 'Parâmetros' seria melhor para sua configuração. Use o vocabulário específico associado ao contexto de um módulo para sua vantagem e crie nomes exclusivos que possuem exclusividade, mesmo quando misturados em outros espaços para nome. Acho que isso pode ser uma resposta à pergunta 2 do OP.
4) Refatorar o código para que você não precise misturar o uso da configuração de dois lugares diferentes. Detalhes disso são com você.
5) Combine as duas configurações em uma antes de passar para sua classe. Use uma classe conf combinada para representar:
Os nomes curtos das variáveis de membro agora estão conseguindo o mesmo que aliasing a classe / namespace.
fonte
Parece estranho que adicionar um ponto ao nome o incomode.
Se ambas as configurações
Smurf
eWartmonger
usadas em conjunto em um local, mas separadamente, são usadas em vários locais - o espaço para nome é definitivamente uma boa abordagem.Tendo namespace dará possibilidade de usar nomes "limpos" em código interno, onde com prefixos que você acaba usando
SmurfConfiguration
dentroSmurfService
do código interno, o que pode tornar-se cada vez chato você abrir esse código.fonte