As pastas em uma solução devem corresponder ao espaço para nome?


129

As pastas em uma solução devem corresponder ao espaço para nome?

Em um dos projetos de minha equipe, temos uma biblioteca de classes que possui muitas subpastas no projeto.

Nome do projeto e Namespace: MyCompany.Project.Section.

Dentro deste projeto, existem várias pastas que correspondem à seção de namespace:

  • Pasta Vehiclestem classes no MyCompany.Project.Section.Vehiclesespaço para nome
  • Pasta Clothingtem classes no MyCompany.Project.Section.Clothingespaço para nome
  • etc.

Dentro desse mesmo projeto, há outra pasta desonesta

  • Pasta BusinessObjectstem classes no MyCompany.Project.Sectionespaço para nome

Existem alguns casos como este em que pastas são criadas para "conveniência organizacional".

Minha pergunta é: Qual é o padrão? Nas bibliotecas de classes, as pastas geralmente correspondem à estrutura do namespace ou é uma mistura de itens?


9
Nota: O ReSharper reclamará se os espaços para nome não corresponderem à hierarquia de pastas.
Fred

Respostas:


77

Além disso, observe que, se você usar os modelos internos para adicionar classes a uma pasta, eles serão, por padrão, colocados em um espaço para nome que reflete a hierarquia de pastas.

As aulas serão mais fáceis de encontrar e, por si só, devem ser razões boas o suficiente.

As regras que seguimos são:

  • O nome do projeto / montagem é o mesmo que o espaço para nome raiz, exceto a terminação .dll
  • A única exceção à regra acima é um projeto com um .Core finalizado, o .Core é retirado
  • Pastas iguais a namespaces
  • Um tipo por arquivo (classe, estrutura, enum, delegar etc.) facilita a localização do arquivo certo

1
+1 para "Somente a exceção à regra acima é um projeto com um .Core finalizado, o .Core é retirado" sozinho. Eu tenho uma MyProject.Core.dllmontagem e todas as aulas começam MyProject.Core. Retirar o .Coresufixo faz muito mais sentido.
Luiz Damim 24/04

2
Outra exceção que posso acrescentar é a Exceções. As exceções já possuem o sufixo 'Exception', portanto, um espaço para nome adicional é redundante. Também pode ficar confuso ter parte do espaço de nomes com a palavra Exception (pode levar a System.Exception). No entanto, organizá-los em pastas é bastante útil.
Phillipwei

55

Não.

Eu tentei ambos os métodos em projetos pequenos e grandes, tanto com um (eu) como com uma equipe de desenvolvedores.

Eu achei que a rota mais simples e mais produtiva era ter um único espaço para nome por projeto e todas as classes entram nesse espaço para nome. Você é livre para colocar os arquivos de classe nas pastas de projeto que desejar. Não há problema em adicionar instruções de uso na parte superior dos arquivos o tempo todo, pois existe apenas um único espaço para nome.

É importante organizar os arquivos de origem em pastas e, na minha opinião, é para isso que todas as pastas devem ser usadas. Exigir que essas pastas também sejam mapeadas para namespaces é desnecessário, cria mais trabalho, e eu achei que era realmente prejudicial à organização porque o ônus adicional incentiva a desorganização.

Tome este aviso do FxCop por exemplo:

CA1020: Evite namespaces com poucos tipos
: Um namespace diferente do namespace global contém menos de cinco tipos https://msdn.microsoft.com/en-gb/library/ms182130.aspx

Esse aviso incentiva o despejo de novos arquivos em uma pasta genérica Project.General, ou mesmo na raiz do projeto até que você tenha quatro classes semelhantes para justificar a criação de uma nova pasta. Isso vai acontecer?

Localizando arquivos

A resposta aceita diz: "As aulas serão mais fáceis de encontrar e isso por si só deve ser uma razão suficientemente boa".

Eu suspeito que a resposta está se referindo a ter vários namespaces em um projeto que não são mapeados para a estrutura de pastas, e não ao que estou sugerindo, que é um projeto com um único namespace.

De qualquer forma, embora não seja possível determinar em qual pasta um arquivo de classe está no namespace, você pode encontrá-lo usando Ir para definição ou a caixa do explorador de soluções de pesquisa no Visual Studio. Além disso, isso não é realmente um grande problema na minha opinião. Não gasto nem 0,1% do meu tempo de desenvolvimento com o problema de encontrar arquivos para justificar a otimização.

Conflitos de nome

A criação de vários espaços para nome permite que o projeto tenha duas classes com o mesmo nome. Mas isso é realmente uma coisa boa? Talvez seja mais fácil simplesmente impedir que isso seja possível? Permitir duas classes com o mesmo nome cria uma situação mais complexa, em que 90% das vezes as coisas funcionam de uma certa maneira e, de repente, você descobre que tem um caso especial. Digamos que você tenha duas classes Rectangle definidas em namespaces separados:

  • classe Project1.Image.Rectangle
  • classe Project1.Window.Rectangle

É possível encontrar um problema em que um arquivo de origem precisa incluir os dois namespaces. Agora você deve escrever o espaço para nome completo em qualquer lugar desse arquivo:

var rectangle = new Project1.Window.Rectangle();

Ou mexa com alguma declaração desagradável de uso:

using Rectangle = Project1.Window.Rectangle;

Com um único espaço para nome em seu projeto, você é forçado a criar nomes diferentes, e eu argumentaria mais descritivos, como este:

  • classe Project1.ImageRectangle
  • classe Project1.WindowRectangle

E o uso é o mesmo em qualquer lugar, você não precisa lidar com um caso especial quando um arquivo usa os dois tipos.

usando instruções

using Project1.General;  
using Project1.Image;  
using Project1.Window;  
using Project1.Window.Controls;  
using Project1.Shapes;  
using Project1.Input;  
using Project1.Data;  

vs

using Project1;

A facilidade de não precisar adicionar espaços para nome o tempo todo enquanto escreve código. Não é o tempo que leva realmente, é a interrupção no fluxo de ter que fazer isso e apenas o preenchimento de arquivos com muitas instruções de uso - para quê? Vale a pena?

Alterando a estrutura da pasta do projeto

Se as pastas são mapeadas para espaços de nome, o caminho da pasta do projeto é efetivamente codificado em cada arquivo de origem. Isso significa que qualquer renomeação ou movimentação de um arquivo ou pasta no projeto exige que o conteúdo real do arquivo seja alterado. A declaração de namespace dos arquivos nessa pasta e o uso de instruções em vários outros arquivos que fazem referência a classes nessa pasta. Embora as alterações sejam triviais com as ferramentas, geralmente resulta em uma confirmação grande, consistindo em muitos arquivos cujas classes nem sequer foram alteradas.

Com um único espaço para nome no projeto, você pode alterar a estrutura da pasta do projeto da maneira que desejar, sem que os arquivos de origem sejam modificados.

O Visual Studio mapeia automaticamente o espaço para nome de um novo arquivo para a pasta do projeto em que é criado.

Lamentável, mas acho que o aborrecimento de corrigir o espaço para nome é menor do que o aborrecimento de lidar com eles. Também adquiri o hábito de copiar colando um arquivo existente em vez de usar Adicionar-> Novo.

Intellisense e Pesquisador de Objetos

Na minha opinião, o maior benefício do uso de vários espaços para nome em grandes projetos é ter organização extra ao exibir classes em qualquer ferramenta que exibe classes em uma hierarquia de espaços para nome. Mesmo documentação. Obviamente, ter apenas um espaço para nome no projeto resulta em todas as classes sendo exibidas em uma única lista em vez de divididas em categorias. No entanto, pessoalmente, nunca fiquei perplexo ou atrasado devido à falta disso, por isso não considero um benefício grande o suficiente para justificar vários espaços para nome.

Embora se eu estivesse escrevendo uma grande biblioteca de classe pública , provavelmente usaria vários espaços para nome no projeto para que o assembly parecesse limpo nas ferramentas e na documentação.


30
Essa é honestamente uma das soluções mais pesadelos que ouvi sugerida. Se você trabalha em pequenos projetos hello world, esse conselho funciona, mas imagine que você tenha mais de 1000 arquivos .cs. Causaria tantos problemas que não sei por onde começar.
precisa saber é o seguinte

10
"mas imagine que você tem mais de 1000 arquivos .cs". Eu trabalhei em projetos desse tamanho com um único espaço para nome. Está bem. Que desastre você acha que aconteceria?
Weyland Yutani

14
+1 por pensar. Acho que não estou pronto para reduzir meus namespaces a um por projeto, mas depois de trabalhar em uma grande estrutura, estou explorando a redução do número de namespaces para reduzir o número de instruções de uso e para ajudar na descoberta de métodos de extensão. Penso que esta resposta fornece um bom alimento para reflexão. Obrigado.
Lee Gunn

3
@WeylandYutani sei que estou atrasado, mas preciso mencionar que esta frase: you can find it by using Go To Definition or the search solution explorer box in Visual Studionem sempre é verdadeira. Experimente bastante herança e interfaces ... boa sorte em encontrar o arquivo certo.
Emmanuel M.

11
Este é um dos melhores conselhos que já vi. Os espaços para nome são apenas para resolução de conflitos, não para organizar classes. Use espaços para nome apenas onde fizer sentido usá-los, como onde você espera ter conflitos de nomes com outros projetos que possam estar usando o seu projeto, permitindo que determinados espaços para nome sejam incluídos ou excluídos com instruções de uso. É terrível ter um projeto com 3 ou 4 ou mais namespaces usados ​​com freqüência, porque sempre resulta em um número ridículo de instruções de uso que você precisa adicionar e adicionar e adicionar e adicionar. Divida seus projetos.
Triynko

31

Acho que o padrão, dentro do .NET, é tentar fazê-lo quando possível, mas não criar estruturas desnecessariamente profundas apenas para aderir a ela como uma regra rígida. Nenhum dos meus projetos segue a regra de estrutura namespace == 100% do tempo, às vezes é mais limpo / melhor sair dessas regras.

Em Java, você não tem escolha. Eu chamaria isso de um caso clássico do que funciona em teoria versus o que funciona na prática.


1
Eu diria "faça quando você realmente quiser que algo esteja em seu próprio espaço de nome". Deve ser uma decisão consciente. Se seus projetos estiverem adequadamente isolados, deve haver um espaço para nome por projeto. Se sua classe estiver em um espaço para nome, ela deverá estar em uma pasta com esse espaço para nome OU em um local da subpasta que seja pelo menos tão específico quanto o espaço para nome. Uma classe como Car.Ford.Fusion (se Car.Ford for seu único espaço para nome) deve estar em uma pasta como Car / Ford OU mais profunda como Car / Ford / Sedans, de modo que a pasta seja pelo menos tão específica quanto o espaço para nome. Apenas não o coloque em Carro / Não relacionado / Ford; isso é confuso.
Triynko

25

@assevk: Eu concordo com essas regras e tenho mais uma a acrescentar.

Quando aninhei classes, ainda as divido, uma por arquivo. Como isso:

// ----- Foo.cs
partial class Foo
{
    // Foo implementation here
}

e

// ----- Foo.Bar.cs
partial class Foo
{
    class Bar
    {
        // Foo.Bar implementation here
    }
}

5

Eu diria que sim.

Primeiro, será mais fácil encontrar os arquivos de código reais seguindo os espaços de nome (digamos, quando alguém lhe enviar uma pilha de chamadas de exceção nua). Se você deixar suas pastas fora de sincronia com os espaços para nome, encontrar arquivos em grandes bases de código se tornará cansativo.

Segundo, o VS gerará novas classes criadas em pastas com o mesmo espaço para nome de sua estrutura de pastas pai. Se você decidir nadar contra isso, será apenas mais um trabalho de encanamento a ser realizado diariamente ao adicionar novos arquivos.

Obviamente, isso é desnecessário dizer que é preciso ser conservador quanto à profundidade da hierarquia das pastas / namespaces.


4

Sim, deveriam, apenas leva à confusão caso contrário.


2

Qual é o padrão?

Não existe um padrão oficial, mas convencionalmente o padrão de mapeamento de pasta para namespace é o mais amplamente usado.

Nas bibliotecas de classes, as pastas geralmente correspondem à estrutura do namespace ou é uma mistura de itens?

Sim, na maioria das bibliotecas de classes, as pastas correspondem ao namespace para facilitar a organização.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.