Suddivisione in file: quanto suddivisione?


9

Se dico di avere un framework di entità gerarchico, piuttosto che un modello di componente. Qualcosa del tipo:
(Sì, questo è inventato)

Arma-> Pistola-> Pistola automatica-> MP44
O, più di un esempio classico:
Entità-> MovableEntity-> Enemy-> WalkingEnemy

Quanto lontano divideresti i file sorgente / intestazione per leggibilità e organizzazione? È meglio andare qualcosa come Entity.cpp, MovableEntity.cpp, Enemy.cpp, ecc. O sarebbe meglio un approccio come Entity.cpp [contenente Entity e MovableEntity] e Enemy.cpp [contenente Enemy e WalkingEnemy]? (O in un modo agnostico più linguistico, un file Enemy e un file Entity rispetto a un file per ogni classe?)
Inoltre, ciò influirebbe su qualcosa di diverso dalla leggibilità e dall'organizzazione?


1
Nitpicky, ma non credo language-agnosticsia un tag appropriato poiché dipende molto dal linguaggio che stai usando per quanto riguarda gli effetti collaterali.
Tetrad,

Buon punto, penso di poterlo ripetere.
Il comunista Duck il

Risposte:


12

Questa è interamente una questione di preferenza. Tuttavia, personalmente credo che sia meglio sbagliare sul lato di più file. Java richiede una classe per file , con il nome del file uguale al nome della classe, ad esempio; lo fanno per politica per far rispettare questa buona pratica (sebbene si possano avere sottoclassi che sostanzialmente aggirano questo).

Inoltre, i sistemi di controllo del codice sorgente sono piuttosto efficaci nell'unire le modifiche in un file, ma è meno seccante se lavori solo in file totalmente separati. Puoi anche vedere più facilmente chi ha cambiato la classe. Supponiamo che un altro sviluppatore apporti una modifica al file AllEntities.h; non hai idea di quale entità (o entità) abbia cambiato fino a quando non apri il file e guardi l'output diff.

È comunque fantastico raggruppare piccole strutture ed enumerazioni relative alla classe all'interno del file di una classe . Se hai un enum che viene utilizzato solo da una singola classe, perché dividerlo nel suo file? Mettili insieme. Ma se viene utilizzato da un'altra classe (ovvero un altro membro della classe è di questo tipo enum), è allora che è tempo di dargli il proprio file.


Concordato. La complessità dei tuoi tipi dovrebbe sicuramente essere un fattore. Se il tuo linguaggio supporta classi parziali (o se le implementazioni dei membri possono essere organizzate in modo simile al C ++), consiglierei anche di suddividere tipi particolarmente complessi in più file. Ad esempio, se c'è un'interfaccia (grande) che la tua classe deve implementare, ma il codice è abbastanza generico e non terribilmente rilevante per il resto, potresti suddividere quel codice in un file separato / classe parziale. Per i tipi di enum, penso che potresti cavartela mettendo tutti gli enum per un determinato spazio dei nomi in un singolo file.
Mike Strobel,

1
Raggruppare i tuoi enum significa che cambiare un singolo valore causerebbe una ricompilazione di ogni file che utilizza un enum in quello spazio dei nomi?
Il comunista Duck il

Bene, questo dipende davvero dalla lingua, ma sì, potrebbe sicuramente avere questo effetto. Non è davvero un problema per me, poiché sviluppo principalmente in C # (nessuna compilazione file per file), ma potrebbe essere problematico in C ++ e in altre lingue. Come sempre, ci sono fattori specifici della lingua da considerare, e quello sarebbe uno di questi :).
Mike Strobel,

2

Molte lingue al di fuori di C / C ++ impongono vincoli ai file. Ricket menzionava "una classe per file" di Java; Python utilizza i file come spazi dei nomi; altre lingue spesso copiano lo spirito di quelli.

Se si utilizza C o C ++, più file inclusi in genere significano tempi di compilazione più lunghi per file; d'altra parte, meno significa di più da ricompilare quando si apportano piccole modifiche. Poiché le enumerazioni non possono essere dichiarate in avanti in C, è necessario inserirle sempre nei file di intestazione contenenti solo altri enumerati, per motivi di integrità delle dipendenze.

Altrimenti, "un file per classe" di Java è ragionevole, ma per molto tempo Java ha supportato le classi interne - come un contenitore e una classe interna del suo iteratore. Allo stesso modo in qualsiasi altra lingua probabilmente vorrai un record / struttura / classe / tipo / interfaccia / blorb dominante per intestazione, ma potresti decidere di includere anche helper o container correlati.

(Non è necessario utilizzare un modello di componente, ma se si dispone di una gerarchia di classi profonda e specifica come quella, ti odierai più tardi.)


Stavo usando la gerarchia come esempio; Ho sentito che enfatizzava ciò che intendevo meglio. Nel codice reale, mi sto impegnando per i componenti.
Il comunista Duck il
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.