8

Uno dei modi popolari di organizzare directory del progetto è più o meno così:C++ fonte progetto di allestimento codice

 
MyLib 
    +--mylib_class_a.h 
     mylib_class_a.cpp 
     mylib_library_private_helpers.h 
     mylib_library_private_helpers.cpp 

MyApp 
    +--other_class.h 
     other_class.cpp 
     app.cpp 

app.cpp:

#include "other_class.h" 
#include <mylib_class_a.h> // using library MyLib 

Tutti .h e .cpp file per la stessa libreria sono nella stessa directory. Per evitare la collisione dei nomi, i nomi dei file sono spesso prefissi con il nome dell'azienda e/o il nome della libreria. MyLib si troverà nel percorso di ricerca dell'intestazione di MyApp, ecc. Non sono un fan del prefisso dei nomi di file, ma mi piace l'idea di guardare lo #include e sapere esattamente dove si trova quel file di intestazione. Non odio questo approccio all'organizzazione dei file, ma penso che dovrebbe esserci un modo migliore.

Dal momento che sto iniziando un nuovo progetto, desidero sollecitare alcune idee per l'organizzazione delle directory. Attualmente mi piace questa struttura di directory:

 
ProjA 
    +--include 
      +--ProjA 
        +--mylib 
          +--class_a.h 
        +--app 
          +--other_class.h 
    +--src 
     +--mylib 
       +--class_a.cpp 
        library_private_helpers.h 
        library_private_helpers.cpp 
     +--app 
       +--other_class.cpp 
       app.cpp 
       util.h 

app.cpp:

#include "util.h" // private util.h file 
#include <ProjA/app/other_class.h> // public header file 
#include <ProjA/mylib/class_a.h> // using class_a.h of mylib 
#include <other3rdptylib/class_a.h> // class_a.h of other3rdptylib, no name collision 
#include <class_a.h> // not ProjA/mylib/class_a.h 
#include <ProjA/mylib/library_private_helpers.h> // error can't find .h 

.cpp file e privata (visibile solo agli biblioteca immediato) .h file sono memorizzati nella directory src (src è talvolta chiamato lib). I file di intestazione pubblici sono organizzati in una struttura di directory project/lib e inclusi tramite <ProjectName/LibraryName/headerName.h>. I nomi dei file non sono preceduti da nulla. Se avessi mai avuto bisogno di impacchettare MyLib per essere usato da altri team, avrei potuto semplicemente cambiare il mio makefile per copiare i file binari appropriati e l'intera directory include/ProjA.

Una volta che i file vengono controllati nel controllo del codice sorgente e le persone iniziano a lavorarci, sarà difficile cambiare la struttura delle directory. È meglio farlo subito al via.

Chiunque abbia esperienza nell'organizzazione di codice sorgente come questo? Qualcosa che non ti piace a riguardo? Se hai un modo migliore per farlo, mi piacerebbe molto sentirlo.

risposta

8

Bene, tutto dipende da quanto sono grandi questi progetti. Se hai solo pochi file, li colpisci tutti in un'unica cartella.

Troppe cartelle quando non si hanno molti file da gestire è a mio avviso eccessivo. Diventa fastidioso scavare dentro e fuori dalle cartelle quando hai solo pochi file in esse.

Inoltre, dipende da chi sta usando questa roba. Se stai scrivendo una libreria e sarà utilizzata da altri programmatori, allora è bene organizzare le intestazioni che vogliono utilizzare in una cartella di inclusione. Se stai creando un numero di librerie e pubblicandole tutte, allora la tua struttura potrebbe funzionare. Ma se sono librerie indipendenti e lo sviluppo non è tutto fatto insieme e vengono rilasciate e rilasciate in momenti diversi, è meglio che tutti i file per un progetto siano localizzati all'interno di una cartella.

In effetti, direi di tenere tutto in una cartella, finché non arrivi a un punto in cui trovi il suo ingestibile, quindi riorganizza in uno schema intelligente per suddividere la sorgente in cartelle come quelle che hai fatto. Probabilmente saprai come deve essere organizzato dai problemi che incontri.

KISS è in genere sempre la soluzione per la programmazione -> mantenere tutto il più semplice possibile.

+1

Sono d'accordo che sarà eccessivo all'inizio. La mia preoccupazione è quando il progetto si avvia e la crescita a una dimensione decente, nessuno vorrà spendere il tempo per riorganizzare tutti i file e modificare tutti i percorsi di inclusione. –

+4

Beh, potrebbe essere vero. Ma sembri desideroso di tenere tutto in ordine, quindi potresti farlo! Lavoro in un'azienda con circa 60 sviluppatori divisi in team. Un paio di settimane fa un certo numero di team ha trascorso alcuni giorni a riorganizzare i propri file. Mantenere le cose organizzate è un processo in corso .. un buon programmatore di refettori codifica quando diventa fuori controllo, ad esempio quando un file di codice diventa troppo grande da essere difficile da gestire, dovrebbero dividerlo. È lo stesso con una cartella di file. –

+1

Questi team non avrebbero mai potuto prevedere 3 anni fa quale struttura avrebbero bisogno ora. Se avessero provato a indovinare, penso che avrebbero comunque dovuto riorganizzarsi. Quindi, non dovrei preoccuparmene. Se stai cercando di sviluppare una buona pratica all'inizio di un progetto, è meglio passare il tempo a inventare un buon metodo per testare il codice unitamente e come eseguire i test come parte di una build automatizzata ... perché il test unitario è sicuramente qualcosa di difficile da introdurre una volta che sei in corso. –

3

Ho provato entrambi i metodi. Personalmente, mi piace il primo. Capisco l'impulso di mettere tutto in directory più specifiche, ma provoca molte complicazioni eccessive.

Di solito uso questa regola: le applicazioni e le librerie interne utilizzano il primo metodo. Le librerie pubbliche open source usano il secondo metodo. Quando si rilascia il codice, è molto utile se i file di inclusione si trovano in una directory separata.

4

Perché non fare qualcosa di simile al primo, utilizzare solo la directory che MyLib risiede in come parte della direttiva include, che riduce il prefisso di stupido:

#include <MyLib/ClassA.h> 

che ti dice da dove vengono. Per quanto riguarda la seconda scelta, personalmente mi arrabbio molto quando ho aperto un'intestazione o un file sorgente e devo spostarmi nella struttura della directory per trovare l'altro e aprirlo. Con il tuo secondo esempio, se hai aperto src/mylib/class_a.cpp e desideri modificare l'intestazione, in molti editor devi tornare indietro di due livelli, quindi in include/ProjA prima di trovare l'intestazione. E come facciamo a sapere che l'intestazione si trova nella sottodirectory ProjA senza qualche altro indizio esterno? Inoltre, è troppo facile per un file o l'altro spostarsi in un posto diverso che "meglio" rappresenta il modo in cui viene utilizzato, senza spostare il file alternativo. Mi dà solo grattacapi quando lo incontro nel mio lavoro (e abbiamo alcune parti della nostra base di codice in cui le persone hanno fatto tutti i potenziali problemi che ho appena menzionato).

+0

Sì, navigare nella directory sarà un grosso fastidio. Ma un buon editor/IDE aiuterà. gf in VIM o Ctrl-Shift-G in Visual Studio aprirà il file di intestazione per te. So che alcuni sviluppatori collegano semplicemente tutti i file a cui tengono nella propria struttura di directory. –