Più classi in un singolo file .cs - buono o cattivo? [chiuso]


30

È consigliabile creare più classi all'interno di un file .cs o ogni file .cs deve avere una singola classe?

Per esempio:

public class Items
{
    public class Animal
    {
    }

    public class Person
    {
    }

    public class Object
    {
    }
}

Evitando per un minuto il fatto che questo è un cattivo esempio di buona architettura, avere più di una singola classe in un file .cs ha un odore di codice?

Risposte:


30

L'esempio che hai dato in realtà va bene secondo me. Stai dichiarando le classi interne , quindi è perfettamente sensato tenerle nello stesso file . L'unico modo per aggirare questo sarebbe rendere la tua Itemsclasse una classe parziale e dividerla su più file. Considererei questa cattiva pratica. La mia politica generale per le classi nidificate è che dovrebbero essere piccole e private. Ci sono due eccezioni a questo:

  • stai progettando un cluster di classe (più comune in obiettivo-c), quindi potrebbe essere sensato utilizzare l'approccio di classe parziale
  • è necessario un enum che viene utilizzato solo con l'API pubblica della classe genitore. In questo caso preferisco avere un enum pubblico dichiarato all'interno della classe genitore invece di inquinare il mio spazio dei nomi. Essendo l'enum un "enum interno", si ottiene effettivamente un ambito ben definito.

Se formuli la domanda in modo leggermente diverso e chiedi "Dovrei mettere ogni classe di livello dello spazio dei nomi nel suo file", allora la mia risposta sarebbe "sì".

Nel progettare le classi rispettiamo il principio di responsabilità singola. La lettura del codice diventa molto più semplice se la sua forma segue la sua semantica, quindi è ragionevole dividere i file per classe.

Da un punto di vista meccanico, avere un file per classe presenta diversi vantaggi. Puoi aprire più classi contemporaneamente in finestre diverse. Ciò è particolarmente importante poiché nessuno sviluppatore serio lavora con meno di due schermi. Essere in grado di avere più contesto davanti alla mia testa significa che posso mantenere più contesto nella mia testa. (La maggior parte degli IDE ti permetterà di aprire lo stesso file due volte, ma lo trovo imbarazzante).

Il prossimo aspetto importante è il controllo del codice sorgente e la fusione. Mantenendo le classi separate, si evita molta seccatura quando vengono apportate modifiche allo stesso file perché è necessario modificare classi separate.


1
Sono d'accordo, ma poi di nuovo le lezioni interne sono molto rare nella mia esperienza. Per essere onesti, non c'è davvero molto che possa davvero giustificare le classi interne, l'unico caso che conosco sono le classi IEnumerable in cui non ti occupi davvero della classe effettiva finché puoi enumerarla. In tutti gli altri casi, ogni classe dovrebbe ottenere il proprio file. Se per nessun altro motivo a causa di problemi di controllo del codice sorgente.
Homde,

2
Aggiungerei che le classi interne dovrebbero essere un'eccezione rara e quasi mai dovrebbero essere pubbliche.
Josh

Yup mi insegna per essere così veloce, le lezioni interne vanno bene, tuttavia chiedere se dovresti usare gli occhiali è un'altra domanda :)
onore krystan

11

Per essere brutalmente onesti, ti preghiamo di non aggiungere più di una classe root a un file. Nel mio ultimo lavoro, c'erano file con non solo più classi, ma più spazi dei nomi e questo si estendeva in più migliaia di righe di codice. Molto difficile da provare a seguire.

Se sono presenti classi strettamente correlate, denominare i file in modo simile o inserirli in una sottocartella.

La separazione fisica dei file di classe aiuta (notate, non alla fine, tutti) a generare separazione delle preoccupazioni e un accoppiamento più lento.

D'altra parte, il tuo esempio non mostra più di una classe radice. Esistono diverse classi nidificate (nota: cerca di non creare nulla nelle classi nidificate, ma privatese riesci a progettarlo) e questo va benissimo in un unico file.


3
Oddio, sembra terribile.

Perché stai chiedendo? Qualcuno ti ha declassato e vuoi chiederti il ​​perché?

Aspetta ... ti riferivi al piccolo aneddoto sul mio ultimo lavoro? Se è così, ho capito male e mi scuso per questo.
Jesse C. Slicer,

Sono completamente d'accordo. Sto lavorando a un progetto in cui la maggior parte dei file ha almeno 4 classi per file. E alcuni hanno fino a 22 classi + 1 interfaccia per file.
L_7337,

7

Se i file sono molto coerenti, ad esempio dove è un'alternativa ad avere molti file molto brevi, con nomi simili, allora può essere una buona idea.

Ad esempio, trovo che quando utilizzo Fluor NHibernate è più facile se lo conservo EntityeEntityMap in un singolo file, nonostante ciò che i miei strumenti potrebbero dire al riguardo.

Nella maggior parte dei casi, rende le lezioni più difficili da trovare. Usare con parsimonia e con cautela.


1
Soprattutto per Fluent NHibernate, ho trovato utile tenerli non solo nello stesso file, ma anche nella stessa classe. Tutte le mie entità hanno una classe nidificata chiamata Mappa.
James Beninger,

7

In poche parole sì, non è una buona forma per farlo e ti dirò perché, un po 'più tardi quando la tua soluzione diventerà grande ti dimenticherai dove sono le classi poiché il nome del file non rappresenterà più quali sono i contenuti, qual è il nome del file AnimalPersonObject.cs non è fattibile.

Sicuramente puoi aggirare questo problema usando le funzionalità di strumenti come resharper per passare ai tipi, ma 1 classe per file (comprese le interfacce) è davvero la spina dorsale di qualsiasi codice standard che abbia mai visto, non solo in .net ma in java e c ++ e molte altre lingue, quelle che non hanno spesso problemi di manutenzione e troverai sviluppatori minori che trovano difficile capire il codice.

Quasi tutti gli strumenti di ottimizzazione del codice ti diranno di spostare le classi in un file separato, quindi per me sì questo è un odore di codice e ha bisogno di un po 'di estro per neutralizzarlo :)


3

Un altro problema è che con classi molto grandi e simili nello stesso file - quando non riesci a vedere la dichiarazione di classe in ogni momento - potresti finire per mettere punti di interruzione nella classe sbagliata e chiederti perché non vengono colpiti ... grrr! :)


-3

Fondamentalmente, se hai solo bisogno di usare questa classe all'interno della classe "parent" (in termini di ambito), di solito è opportuno definirla come una classe nidificata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.