Estou construindo bibliotecas com várias pequenas funções utilitárias em C # e tentando decidir sobre um espaço para nome e convenção de nomenclatura de classe. Minha organização atual é assim:
Company
Company.TextUtils
public class TextUtils {...}
Company.MathsUtils
public class MathsUtils {...}
public class ArbitraryPrecisionNumber {...}
public class MathsNotation {...}
Company.SIUnits
public enum SISuffixes {...}
public class SIUnits {...}
Essa é uma boa maneira de organizar o namespace e as classes, ou existe uma maneira melhor? Em particular, parece que ter o mesmo nome no namespace e no nome da classe (por exemplo, Company.TextUtils
namespace e TextUtils
classe) é apenas duplicação e sugere que o esquema poderia ser melhor.
SISuffix
invés deSISuffixes
), e acho que o singular é melhor.Suffix.A
lê como "sufixo A". Além disso, geralmente evito repetir nomes de um nível acima na hierarquia. Ou seja, em vez deCompany.SIUnits.SISuffixes
, eu me inclinaria paraCompany.SI.Suffix
eCompany.SI.Unit
Respostas:
É muito difícil determinar a eficácia da sua estratégia de nomenclatura isolada do restante do seu código.
O espaço para nome deve dar uma idéia de onde ele se encaixa na ampla estrutura da sua base de código, e o nome da classe geralmente descreveria que tipo de funcionalidade ou conceito ele representa nessa área.
Advertências à parte, em seu exemplo específico, se é provável que você tenha muito mais classes do tipo 'Util', consideraria colocá-las em
Company.Utils.Maths
etc. etc. Dessa forma, se você precisar adicionar funcionalidades comuns a várias áreas de utilidades, você já terá um local natural para isso.fonte
Há um bom documento que contém muitas regras que você deve seguir para estar alinhado com a Microsoft: Diretrizes de Design da Estrutura .
Uma coisa que você deve alterar: não nomeie classes como seu espaço para nome. Isso levará a misturas de compiladores. Apenas não. Encontre um nome melhor para a classe do espaço para nome.
fonte
Já faz um tempo desde que eu trabalhei com C # ou o ecossistema .NET, então não posso dizer quais são as melhores práticas recomendadas atualmente. Eu recomendaria uma alteração nos seus nomes assim:
O que eu fiz aqui é remover "Utils" dos nomes de namespace. Eu acho que "Util" não deve estar em um espaço para nome, porque o
Company.Text
espaço para nome poderia um dia conter classes que não são classes de utilitário de texto. OCompany.Math
espaço para nome já contém oArbitraryPrecisionNumber
que não parece ser um "utilitário".A remoção de "Util" do espaço para nome também elimina qualquer confusão que possa surgir com duas coisas com o mesmo nome (conforme mencionado na resposta de Robert: /software//a/340440/13156 )
Outra maneira de organizar o código:
Nesse caso, todas as classes de utilitário residem no mesmo espaço para nome. Não há mais
Company.Text
espaço para nome, pois a única coisa que havia uma classe de utilitário.Pessoalmente, acho a primeira opção um pouco mais clara.
fonte
Usar o mesmo nome para o espaço para nome e a classe dentro dele é problemático.
Se o espaço para nome contiver mais de uma classe, por que outras classes seriam colocadas lá? não parece certo, porque o objetivo do nome do espaço para nome é descrever todas as classes dentro dele, não apenas uma. Por exemplo, se você tem
JsonSerialization
,BinarySerialization
eXmlSerialization
classes em um namespace, faria sentido para nomear seu namespaceXmlSerialization
?O que geralmente acontece é que, devido à extração de uma classe de um espaço para nome existente ou a uma mesclagem entre várias classes ou outra reorganização, você se encontra com um espaço para nome que contém uma classe principal ; progressivamente, classes menores são colocadas lá porque estão um pouco relacionadas à classe original. Por exemplo, um espaço para nome
LogParser
pode conter uma única classeLogParser
e alguém o colocaLogConverter
, porque é bastante relacionado ao analisadorLogSearcher
, etc. O problema aqui é que o nome do espaço para nome não foi alterado: assim queLogConverter
foi adicionado, o O nome deveria ter sido alterado paraLogsProcessing
ou, simplesmenteLogs
,.Se o espaço para nome contiver apenas uma classe, pode ser um sinal de um problema na organização do código.
Embora eu tenha visto algumas vezes as situações em que uma única classe com princípios SOLID adequados era muito diferente de qualquer outra coisa na base de código e, portanto, foi colocada em um espaço de nome dedicado, esses casos são raros. Mais frequentemente, isso é indicativo de um problema. Da mesma forma, nada impede que você tenha uma classe contendo um único método, mas, na maioria das vezes, essas classes indicariam um problema.
Mesmo que seu espaço para nome contenha apenas uma classe, geralmente há uma maneira de ser mais específico ao nomear a classe e mais geral ao nomear o espaço para nome. Imagine um aplicativo que, entre outras coisas, deve, em um determinado momento, converter arquivos escritos no formato ABC para o formato DEF. A conversão não requer desserialização / serialização de / para os objetos de negócios e é feita aplicando várias expressões regulares curtas o suficiente para serem colocadas na própria classe de conversão chamada
AbcToDefConverter
. Toda a lógica de conversão leva cerca de 80 LLOC em cerca de dez métodos interdependentes - parece uma situação em que não há absolutamente nenhuma necessidade de dividir a classe existente, nem criar classes adicionais. Como a parte restante do aplicativo não tem nada a ver com conversões, a classe não pode ser agrupada com outras classes nos namespaces existentes. Então, cria-se um espaço para nome chamadoAbcToDefConverter
. Embora não haja nada inerentemente errado nisso, também é possível usar um nome mais genérico, comoConverters
. Em linguagens como Python, onde nomes mais curtos são preferidos e repetição é aplicada, pode até se tornarconverters.Abc_To_Def
.Portanto, use nomes diferentes para namespaces e para as classes que eles contêm. O nome de uma classe deve indicar o que a classe está fazendo, enquanto o nome do espaço para nome deve destacar o que é comum em todas as classes inseridas nela.
A propósito, as classes de utilidade são erradas por natureza: em vez de conter algo específico, como aritmética de precisão arbitrária, elas contêm tudo o que não foi encontrado em outras classes . Isso é simplesmente uma má nomeação, assim como um
Miscellaneous
diretório em uma área de trabalho - algo que é indicativo da falta de organização.A nomeação existe por um motivo: para facilitar sua vida quando você precisar encontrar coisas mais tarde. Você sabe que, se precisar desenhar um gráfico, tente procurar "gráfico" ou "plot". Quando você precisar alterar a maneira como um aplicativo gera faturas, você pesquisará "fatura [e / ing]" ou "fatura". Da mesma forma, tente imaginar um caso em que você dirá para si mesmo: "hm, esse recurso provavelmente deve ser encontrado em diversos". Eu não posso
Veja o .NET Framework. A maioria dessas classes não é de utilidade? Quero dizer, eles têm poucas coisas a ver com o domínio comercial. Se eu trabalho em um aplicativo financeiro, site de comércio eletrônico ou na plataforma educacional de próxima geração, serializar XML ou ler arquivos ou fazer consultas SQL ou realizar transações é tudo de utilidade. No entanto, eles não são chamados
UtilitySerialization
ouUtilityTransaction
e não estão noUtility
espaço para nome. Eles têm nomes próprios, o que torna possível (e fácil, obrigado desenvolvedores do .NET!) Encontrá-los quando eu precisar deles.O mesmo vale para as aulas que você geralmente reutiliza em seus aplicativos. Eles não são classes de utilidade. São classes que fazem certas coisas, e as coisas que fazem devem realmente ser os nomes das classes.
Imagine que você criou um código que lida com unidades e conversão de unidades. Você pode nomear
Utility
e ser odiado por seus colegas; ou você pode nomearUnits
eUnitsConversion
.fonte
Math
? Não vejo como adicionarUtility
sufixo a tudo tornaria nossa vida mais fácil. Ao usar oSystem.Math.Min()
método .NET , você prefere realmente escreverSystemUtility.MathUtility.Min()
? Em todos os casos, editei fortemente minha resposta, por isso deve ficar mais clara agora.