Várias classes em um único arquivo .cs - bom ou ruim? [fechadas]

30

É aconselhável criar várias classes em um arquivo .cs ou cada arquivo .cs deve ter uma classe individual?

Por exemplo:

public class Items
{
    public class Animal
    {
    }

    public class Person
    {
    }

    public class Object
    {
    }
}

Esquivando-se por um minuto que este é um exemplo ruim de boa arquitetura, está tendo mais de uma classe em um arquivo .cs um cheiro de código?


fonte

Respostas:

30

O exemplo que você deu é realmente bom na minha opinião. Você está declarando classes internas , portanto, é perfeitamente sensato mantê-las no mesmo arquivo . A única maneira de contornar isso seria tornar sua Itemsclasse uma classe parcial e dividi-la em vários arquivos. Eu consideraria essa má prática. Minha política geral para classes aninhadas é que elas sejam pequenas e particulares. Existem duas exceções para isso:

  • você está projetando um cluster de classes (mais comum no objetivo-c), portanto, pode ser sensato usar a abordagem de classe parcial
  • você precisa de uma enumeração usada apenas com a API pública da classe pai. Nesse caso, prefiro ter uma enumeração pública declarada dentro da classe pai em vez de poluir meu namespace. O enum sendo um "enum interno" efetivamente resulta em um escopo bem definido.

Se você escrever a pergunta um pouco diferente e perguntar sobre "Devo colocar cada classe de nível de namespace em seu próprio arquivo", minha resposta será "sim".

Ao projetar aulas, respeitamos o Princípio da Responsabilidade Única. A leitura do código se torna muito mais fácil se sua forma seguir sua semântica, portanto, a divisão de arquivos por classe é sensata.

Do ponto de vista mecânico, ter um arquivo por classe tem várias vantagens. Você pode abrir várias classes ao mesmo tempo em janelas diferentes. Isso é especialmente importante, pois nenhum desenvolvedor sério trabalha com menos de duas telas. Ser capaz de ter mais contexto em frente da minha cabeça significa que eu posso manter mais contexto em minha cabeça. (A maioria dos IDEs permite abrir o mesmo arquivo duas vezes, mas acho isso estranho).

O próximo aspecto importante é o controle de origem e a mesclagem. Ao manter suas classes separadas, você evita muitos problemas quando são feitas alterações no mesmo arquivo, porque as classes separadas precisam ser alteradas.

Johannes Rudolph
fonte
11
Eu concordo, mas, novamente, as classes internas são muito incomuns em minha experiência. Para ser justo, não há realmente muita coisa que possa justificar as classes internas, o único caso que conheço são as classes IEnumerable, nas quais você realmente não é sobre a classe real, desde que possa enumerá-la. Nos demais casos, cada classe deve ter seu próprio arquivo. Se não por outro motivo, devido a problemas de controle de origem.
Homde 28/02
2
Eu acrescentaria que as classes internas devem ser uma exceção rara e quase nunca devem ser públicas.
Josh
Yup ensina-me por ser tão rápido fora da marca, classes internas são bons, no entanto perguntando se você deve usar innerclasses é outra questão :)
honra krystan
11

Para ser brutalmente honesto, não adicione mais de uma classe raiz a um arquivo. No meu último trabalho, havia arquivos com não apenas várias classes, mas vários espaços para nome e isso se estendia aos milhares de linhas de código. Muito difícil de tentar seguir.

Se houver classes estreitamente relacionadas, nomeie seus arquivos da mesma forma ou coloque-os em uma subpasta.

A separação física dos arquivos de classe ajuda (note que não é o fim de tudo) a gerar uma separação de preocupações e um acoplamento mais flexível.

Por outro lado, seu exemplo não está mostrando mais de uma classe raiz. Existem várias classes aninhadas (nota: tente não criar classes aninhadas, a não ser privateque você possa projetar isso) e é perfeitamente bom ter isso em um arquivo.

Jesse C. Slicer
fonte
3
Oh Deus - isso parece terrível.
Porque perguntas? Alguém te recusou e você quer perguntar por quê?
Espere ... você estava se referindo à pequena anedota sobre o meu último emprego? Nesse caso, entendi errado e peço desculpas por isso.
Jesse C. Slicer
Concordo completamente. Estou trabalhando em um projeto em que a maioria dos arquivos tem pelo menos 4 classes por arquivo. E alguns têm até 22 classes + 1 interface por arquivo.
L_7337
7

Se os arquivos forem altamente coesos, por exemplo, onde é uma alternativa a ter vários arquivos muito curtos e com nomes semelhantes, pode ser uma boa ideia.

Por exemplo, acho que ao usar o Fluent NHibernate é mais fácil manter Entitye EntityMapem um único arquivo, apesar do que minhas ferramentas possam ter a dizer sobre isso.

Na maioria dos casos, apenas torna as aulas mais difíceis de encontrar. Use com moderação e cautela.

mootinator
fonte
11
Especificamente para o Fluent NHibernate, achei útil mantê-los não apenas no mesmo arquivo, mas na mesma classe. Todas as minhas entidades têm uma classe aninhada chamada Map.
James Beninger 22/08/2012
7

Simplificando, sim, não é uma boa forma de fazer isso e vou lhe dizer por que, um pouco mais tarde, quando sua solução se tornar grande, você esquecerá onde estão as classes, pois o nome do arquivo não representará mais o conteúdo, qual é o nome do arquivo AnimalPersonObject.cs isso não é viável.

Claro que você pode contornar isso usando recursos em ferramentas como o ressarpador para pular para tipos, mas 1 classe por arquivo (incluindo interfaces) é realmente a espinha dorsal de qualquer padrão de código que eu já vi, não apenas em .net, mas em java e java. c ++ e muitas outras linguagens, aquelas que geralmente não têm problemas de manutenção e você encontrará desenvolvedores juniores com dificuldade em entender o código.

Quase todas as ferramentas de otimização de código dizem para você mover as classes para um arquivo separado. Portanto, para mim, sim, esse é um cheiro de código e precisa de alguma remoção para neutralizá-lo :)

honra do krystan
fonte
3

Outra questão é que, com classes muito grandes e similares no mesmo arquivo - quando você não pode ver a declaração da classe o tempo todo -, você pode acabar colocando pontos de interrupção na classe errada e se perguntando por que eles não são atingidos ... grrr! :)

Julia Hayward
fonte
-3

Basicamente, se você precisar usar essa classe somente dentro da classe "pai" (em termos de escopo), geralmente é apropriado defini-la como uma classe aninhada.

hjdjdg
fonte