[C] Strutturazione programma a più moduli

di il
15 risposte

[C] Strutturazione programma a più moduli

Salve a tutti, sto facendo dei progetti per un esame, e per la prima volta mi trovo davanti ad un codice un po' più robusto che ai fini di flessibilità e riusabilità credo andrebbe un po' suddiviso in moduli, però ho dei dubbi in merito che spero qualcuno possa aiutare a risolvere.
Il programma che sto scrivendo è un piccolo gioco dove ho un personaggio e degli avversari. Ovviamente il personaggio ha delle proprietà, e fa dei movimenti che sono diversi da quelli degli avversari. Avevo pensato di mettere tutte le funzioni di gestione del gioco vero e proprio in game.c (con game.h), quelle del personaggio in pac.c (con pac.h), quelle del nemico in enemy.c (con enemy.h) e infine quelle grafiche in view.c (view.h).
Il dubbio che mi sorge è il seguente.. chiaramente game deve includere tutti gli altri file, ma è preferibile che pac, enemy e view, siano indipendenti da game (nel senso che non devono includere game.h), giusto?! Ad esempio, prima che suddividessi il codice avevo una struttura dati gamestr in game.c (che era l'unico corpo del programma), successivamente siccome il movimento del personaggio andava a modificare dei valori in tale struttura ho pensanto che non andasse bene averla in game.c ma piuttosto creare un altro file game_struct da includere in pac.c (e negli altri file). Ma questo ragionamento è giusto? Spero di essermi spiegata al meglio

15 Risposte

  • Re: [C] Strutturazione programma a più moduli

    Dipende da come hai organizzato il tuo gioco, i dati che hai usato, come li hai usati.
  • Re: [C] Strutturazione programma a più moduli

    oregon ha scritto:


    Dipende da come hai organizzato il tuo gioco, i dati che hai usato, come li hai usati.
    Certo. Ma siccome sono in una fase di apprendimento, mi interessava capire se ai fini di un codice qualitativamente migliore è giusto il problema che mi pongo oppure no. Ad esempio nel caso della struttura dati gamestr, ho fatto bene? Oppure se in pac.c includo game.h non cambia niente? L'idea che game.c include pac.h e pac.c includa game.h credevo fosse "brutta" per cui ho pensato a questa soluzione. Ma siccome, ripeto, sono agli inzi, mi piaceva capire da chi ha più esperienza, in queste circostanze, e simili, qual è la scelta implementativa migliore.
  • Re: [C] Strutturazione programma a più moduli

    Vuoi la risposta banale (cioè a livello universitario italiano), a livello professionale (cioè le raccomandazioni google), o supremo (cioè la verità del 2017)?
  • Re: [C] Strutturazione programma a più moduli

    +m2+ ha scritto:


    Vuoi la risposta banale (cioè a livello universitario italiano), a livello professionale (cioè le raccomandazioni google), o supremo (cioè la verità del 2017)?
    Vorrei il consiglio, che una persona con esperienza in programmazione C, ritenga più giusto dare ad una persona che la sta ancora studiando, a prescindere dal contesto e dal momento storico.
  • Re: [C] Strutturazione programma a più moduli

    Diciamo che i multifile sono nati in un momento (anni 70) in cui i computer erano lentissimi, e si tentava in ogni modo di ridurre i tempi di compilazione, a favore di quelli di linking.
    Inoltre non esistevano nè IDE e neppure editor degni di questo nome, per non parlare di terminali grafici ad alta risoluzione, in grando di avere finestre con ampie porzioni di testo.
    Nè strumenti di ricerca (stile grep) veloci.
    Insomma, nasce tutto nel mondo paleo-informatico.

    Purtroppo rimane, ancor oggi, la tendenza a rifarsi a prassi di una quarantina di anni fa, quando erano necessarie, mentre oggi lo sono molto meno, quando non negative.

    Nessuno ti vieta, infatti, di avere un singolo sorgente da 100MB, tranquillamente "maneggiabile" da compilatori, IDE, editor eccetera odierni.

    Bene, detto tutto questo, potresti spazzar via tutte le "sciocchezze" che vengono propalate in ordine alla compartimentazione logica eccetera (tutta "roba" anni 70), oggi ci sono sistemi di gestione versione eccetera (ecco il livello-google, cioè le raccomandazioni per i suoi dipendenti)

    Siccome, però, sei ancora nella fascia "imparare", vai coi sistemi che insegnano oggi\
  • Re: [C] Strutturazione programma a più moduli

    +m2+ ha scritto:


    Diciamo che i multifile sono nati in un momento (anni 70) in cui i computer erano lentissimi, e si tentava in ogni modo di ridurre i tempi di compilazione, a favore di quelli di linking.
    Inoltre non esistevano nè IDE e neppure editor degni di questo nome, per non parlare di terminali grafici ad alta risoluzione, in grando di avere finestre con ampie porzioni di testo.
    Nè strumenti di ricerca (stile grep) veloci.
    Insomma, nasce tutto nel mondo paleo-informatico.

    Purtroppo rimane, ancor oggi, la tendenza a rifarsi a prassi di una quarantina di anni fa, quando erano necessarie, mentre oggi lo sono molto meno, quando non negative.

    Nessuno ti vieta, infatti, di avere un singolo sorgente da 100MB, tranquillamente "maneggiabile" da compilatori, IDE, editor eccetera odierni.

    Bene, detto tutto questo, potresti spazzar via tutte le "sciocchezze" che vengono propalate in ordine alla compartimentazione logica eccetera (tutta "roba" anni 70), oggi ci sono sistemi di gestione versione eccetera (ecco il livello-google, cioè le raccomandazioni per i suoi dipendenti)

    Siccome, però, sei ancora nella fascia "imparare", vai coi sistemi che insegnano oggi\
    Scusa la mia ignoranza ma cosa esattamente c'entra la gestione della versione del codice con la struttura fisica del progetto !?

    Si è vero che puoi avere un singolo sorgente da 100MB, ma che senso ha ?
  • Re: [C] Strutturazione programma a più moduli

    violet_prog ha scritto:


    Salve a tutti, sto facendo dei progetti per un esame, e per la prima volta mi trovo davanti ad un codice un po' più robusto che ai fini di flessibilità e riusabilità credo andrebbe un po' suddiviso in moduli, però ho dei dubbi in merito che spero qualcuno possa aiutare a risolvere.
    Il programma che sto scrivendo è un piccolo gioco dove ho un personaggio e degli avversari. Ovviamente il personaggio ha delle proprietà, e fa dei movimenti che sono diversi da quelli degli avversari. Avevo pensato di mettere tutte le funzioni di gestione del gioco vero e proprio in game.c (con game.h), quelle del personaggio in pac.c (con pac.h), quelle del nemico in enemy.c (con enemy.h) e infine quelle grafiche in view.c (view.h).
    Il dubbio che mi sorge è il seguente.. chiaramente game deve includere tutti gli altri file, ma è preferibile che pac, enemy e view, siano indipendenti da game (nel senso che non devono includere game.h), giusto?! Ad esempio, prima che suddividessi il codice avevo una struttura dati gamestr in game.c (che era l'unico corpo del programma), successivamente siccome il movimento del personaggio andava a modificare dei valori in tale struttura ho pensanto che non andasse bene averla in game.c ma piuttosto creare un altro file game_struct da includere in pac.c (e negli altri file). Ma questo ragionamento è giusto? Spero di essermi spiegata al meglio
    Lo scopo di suddividere i sorgenti in più moduli è in genere quello di avere più manutenibilità e portabilità. I paradigmi più in voga oggi (MVC, ad esempio) permettono di suddividere il codice in modo tale che se si rende necessario un intervento di correzione o di aggiornamento, si può già identificare il modulo/i in cui intervenire. Inoltre, un progetto suddiviso in moduli può essere sviluppato da più programmatori in contemporanea.
    Un programma con un sorgente monolitico funziona uguale, ma rende complesso intervenire, dato che bisogna navigare tutto il sorgente alla ricerca dei punti su cui mettere le mani, e se per caso sei pasticcione, auguri! (tralascio il fatto che 2+ programmatori con un solo sorgente, la vedo complessa...)
    Il controllo di versione è un punto a parte, funziona uguale sia con più sorgenti che con un monolite. Ci potrebbero essere problemi di performance se il sorgente fosse un file esagerato, ma dipende dal VCS impiegato.
    Quindi puoi fare come ti pare: se opti per un progetto multifile, ti conviene un header comune a tutti i file, più altri header (con le classi/funzioni che sono solo di quel modulo). Attento anche a come scrivi il makefile.
    Personalmente ho sempre preferito i multifile ai monoliti (tranne che per piccoli progetti), e a volte la scelta è stata efficace, altre volte ho toppato il design ed alla fine mi sono trovato con più problemi che soluzioni; in genere era dovuto ad una fase di analisi molto carente, con il cliente che cambiava idea più volte al giorno...
    Nel tuo caso, la scelta dei moduli vs monolite dipende da te: il monolite ti svincola da organizzare le funzioni, ma devi usare un editor molto smart, di quelli che ti visualizzano in un box la lista delle funzioni presenti nel sorgente e la sinossi, altrimenti ti perdi; se usi il multifile, il design migliore è quello in cui uno o più moduli conterranno le funzioni comuni al progetto, e gli altri le varie parti del progetto.
  • Re: [C] Strutturazione programma a più moduli

    Blazgrom ha scritto:


    Scusa la mia ignoranza ma cosa esattamente c'entra la gestione della versione del codice con la struttura fisica del progetto !?

    Si è vero che puoi avere un singolo sorgente da 100MB, ma che senso ha ?
    Che senso ha avere 1000 file da pochi KB ciascuno? Nessuno.
    Anzi, trovare "dove" si trova "qualcosa" non è per nulla banale (non parliamo poi del C++ e dei disastri vari di "visibilità", qui conviene rifarsi alle regole-Google).
    Così come non è per nulla banale far funzionare una compilazione di qualcosa di "grossino" (chiunque utilizzi i port di freebsd lo impara immediatamente), con migliaia di file coinvolti, più o meno incompatibili tra di loro, di versioni diverse, e così via.

    La gestione delle versioni è per lo sviluppo in team.

    Stiamo parlando di programmi C, quindi i vari framework stikazzi non c'entrano nulla.

    ---
    Bene, è un esempio tipico di insegnamento del tipo "si fa così perchè si fa così".
    Pochi si chiedono MA PERCHE' si fa così?
    E ci modi DIVERSI (più o meno validi)?

    Il "perchè si fa così" l'ho già spiegato, risale agli anni '70 (da cui derivano tante belle cose oggi utilizzate, ma spesso sempre in modo acritico, senza pensare).
    Oggi dipende essenzialmente dal TIPO di programma che stai scrivendo, essenzialmente se ha interfaccia GUI oppure no.

    Nel primo caso è abbastanza "logico" (nel senso di "naturale") suddividere il programma collegando alle singole form.
    Avrai la form login, la form inserisci i clienti, la form carica il magazzino eccetera.

    In altri casi, esempio programmi di calcolo, di compressione, crittazione, codifica eccetera, spesso ti trovi con due o 3 file cpp e corrispondenti header (diciamo la libreria a basso livello), perchè è inutile "polverizzare".

    Quindi la risposta è: puoi fare come vuoi, ma tieni presente (ovviamente non ora, che sei un principiante) che adagiarsi su "si fa così perchè mi hanno insegnato così" è il livello diciamo bimbominkiesko-dilettantesco della professione.

    Per ogni cosa che fai chiediti sempre... perchè faccio così? potrei fare cosà? Sarebbe meglio? Peggio? Uguale? Per poi magari concludere che ti conviene fare in un certo modo.

    Ma perchè lo hai SCELTO (oggi va di moda dire "progettato").
  • Re: [C] Strutturazione programma a più moduli

    Andrea Quaglia ha scritto:


    Lo scopo di suddividere i sorgenti in più moduli è in genere quello di avere più manutenibilità e portabilità.
    Fammi un esempio di "portabilità" migliorata da una cosa del genere.
    Così come manutenibilità.
    Perchè è esattamente il contrario
  • Re: [C] Strutturazione programma a più moduli

    +m2+ ha scritto:


    Blazgrom ha scritto:


    Scusa la mia ignoranza ma cosa esattamente c'entra la gestione della versione del codice con la struttura fisica del progetto !?

    Si è vero che puoi avere un singolo sorgente da 100MB, ma che senso ha ?
    Che senso ha avere 1000 file da pochi KB ciascuno? Nessuno.
    Anzi, trovare "dove" si trova "qualcosa" non è per nulla banale (non parliamo poi del C++ e dei disastri vari di "visibilità", qui conviene rifarsi alle regole-Google).
    Così come non è per nulla banale far funzionare una compilazione di qualcosa di "grossino" (chiunque utilizzi i port di freebsd lo impara immediatamente), con migliaia di file coinvolti, più o meno incompatibili tra di loro, di versioni diverse, e così via.

    La gestione delle versioni è per lo sviluppo in team.

    Stiamo parlando di programmi C, quindi i vari framework stikazzi non c'entrano nulla.

    ---
    Bene, è un esempio tipico di insegnamento del tipo "si fa così perchè si fa così".
    Pochi si chiedono MA PERCHE' si fa così?
    E ci modi DIVERSI (più o meno validi)?

    Il "perchè si fa così" l'ho già spiegato, risale agli anni '70 (da cui derivano tante belle cose oggi utilizzate, ma spesso sempre in modo acritico, senza pensare).
    Oggi dipende essenzialmente dal TIPO di programma che stai scrivendo, essenzialmente se ha interfaccia GUI oppure no.

    Nel primo caso è abbastanza "logico" (nel senso di "naturale") suddividere il programma collegando alle singole form.
    Avrai la form login, la form inserisci i clienti, la form carica il magazzino eccetera.

    In altri casi, esempio programmi di calcolo, di compressione, crittazione, codifica eccetera, spesso ti trovi con due o 3 file cpp e corrispondenti header (diciamo la libreria a basso livello), perchè è inutile "polverizzare".

    Quindi la risposta è: puoi fare come vuoi, ma tieni presente (ovviamente non ora, che sei un principiante) che adagiarsi su "si fa così perchè mi hanno insegnato così" è il livello diciamo bimbominkiesko-dilettantesco della professione.

    Per ogni cosa che fai chiediti sempre... perchè faccio così? potrei fare cosà? Sarebbe meglio? Peggio? Uguale? Per poi magari concludere che ti conviene fare in un certo modo.

    Ma perchè lo hai SCELTO (oggi va di moda dire "progettato").
    Un link a queste regole di Google?
  • Re: [C] Strutturazione programma a più moduli

    dvaosta ha scritto:


    +m2+ ha scritto:


    Blazgrom ha scritto:


    Scusa la mia ignoranza ma cosa esattamente c'entra la gestione della versione del codice con la struttura fisica del progetto !?

    Si è vero che puoi avere un singolo sorgente da 100MB, ma che senso ha ?
    Che senso ha avere 1000 file da pochi KB ciascuno? Nessuno.
    Anzi, trovare "dove" si trova "qualcosa" non è per nulla banale (non parliamo poi del C++ e dei disastri vari di "visibilità", qui conviene rifarsi alle regole-Google).
    Così come non è per nulla banale far funzionare una compilazione di qualcosa di "grossino" (chiunque utilizzi i port di freebsd lo impara immediatamente), con migliaia di file coinvolti, più o meno incompatibili tra di loro, di versioni diverse, e così via.

    La gestione delle versioni è per lo sviluppo in team.

    Stiamo parlando di programmi C, quindi i vari framework stikazzi non c'entrano nulla.

    ---
    Bene, è un esempio tipico di insegnamento del tipo "si fa così perchè si fa così".
    Pochi si chiedono MA PERCHE' si fa così?
    E ci modi DIVERSI (più o meno validi)?

    Il "perchè si fa così" l'ho già spiegato, risale agli anni '70 (da cui derivano tante belle cose oggi utilizzate, ma spesso sempre in modo acritico, senza pensare).
    Oggi dipende essenzialmente dal TIPO di programma che stai scrivendo, essenzialmente se ha interfaccia GUI oppure no.

    Nel primo caso è abbastanza "logico" (nel senso di "naturale") suddividere il programma collegando alle singole form.
    Avrai la form login, la form inserisci i clienti, la form carica il magazzino eccetera.

    In altri casi, esempio programmi di calcolo, di compressione, crittazione, codifica eccetera, spesso ti trovi con due o 3 file cpp e corrispondenti header (diciamo la libreria a basso livello), perchè è inutile "polverizzare".

    Quindi la risposta è: puoi fare come vuoi, ma tieni presente (ovviamente non ora, che sei un principiante) che adagiarsi su "si fa così perchè mi hanno insegnato così" è il livello diciamo bimbominkiesko-dilettantesco della professione.

    Per ogni cosa che fai chiediti sempre... perchè faccio così? potrei fare cosà? Sarebbe meglio? Peggio? Uguale? Per poi magari concludere che ti conviene fare in un certo modo.

    Ma perchè lo hai SCELTO (oggi va di moda dire "progettato").
    Un link a queste regole di Google?
    Penso che si riferisce a questi regole: https://google.github.io/styleguide/cppguide.htm.

    @+m2+
    L'unico vantaggio che hai evidenziato per avere un singolo file sorgente è la possibilità di semplificare la compilazione del progetto e su questo sono d'accordo, alla fine la cosa che influenza di più la struttura del progetto e la tipologia del progetto stesso..... o almeno dovrebbe essere cosi .
    Comunque il codice non viene scritto solo per essere eseguito e basta, prima o poi dovrà essere letto da altre persone. Forse sono io quello anormale, ma io personalmente non mi trovo al mio agio a leggere un file lungo centinaia di migliaia di righe.

    In realtà cosi come il principiante deve chiedersi perché fa una cosa anche il professionista dovrebbe chiedersi perché fa una cosa, perché alla fine se il professionista fa una cosa solo per mostrare agli altri che lui può fare qualcosa di diverso rispetto a quello che gli è stato insegnato, lui è solo un finto professionista e niente altro.
  • Re: [C] Strutturazione programma a più moduli

    A dir la verità mi sfugge quale sia la differenza tra leggere X righe in K o M file (con K<>M).
    Sono sempre quelle.

    Il punto l'equilibrio tra un singolo filettone, e un miliardo di filettini diversi (che è quello normalmente insegnato).
    Il "perchè" l'ho già spiegato, e lo ribadisco.

    Quando compili "qualcosa" (tipo apache, mariadb eccetera) piuttosto "grosso", cosa che capita praticamente sempre lavorando con FreeBSD, trovi a compilare (compresi librerie, programmi vari eccetera) decine di migliaia di file (sembra paradossale, ma perfino vim, sì vim, quindi l'editor testuale, ha migliaia e migliaia di file-dipendenze, tanto che normalmente si usa vim-lite).

    Lì vedi subito cosa succede: il caos. Librerie di versioni differenti, incompatibili, linkate male, blocco per versioni tra le più diverse e così via (magari pure incompatibilità sottili e devastanti tra clang\lvmm e gcc, o magari tra gcc "normale" e la versione 4.9, nonostante tutti i pre-test)

    Insomma, compilare "di grosso" programmi C/C++ non è un affare banale, per nulla, cosa mooolto diversa dai "programmini" che normalmente si è abituati a maneggiare.

    Se (per esagerare) apache fosse un singolo filettone, non ci sarebbe nessun problema a compilarlo, basterebbe aspettare il termine.

    D'altronde se devi invece compilare un megaprogetto google, che richiede magari giorni o settimane di compilazione (!), la scala è ancora diversa e i problemi anche.
    As always, common sense and good taste should prevail
  • Re: [C] Strutturazione programma a più moduli

    +m2+ ha scritto:


    A dir la verità mi sfugge quale sia la differenza tra leggere X righe in K o M file (con K<>M).
    Sono sempre quelle.

    Il punto l'equilibrio tra un singolo filettone, e un miliardo di filettini diversi (che è quello normalmente insegnato).
    Il "perchè" l'ho già spiegato, e lo ribadisco.

    Quando compili "qualcosa" (tipo apache, mariadb eccetera) piuttosto "grosso", cosa che capita praticamente sempre lavorando con FreeBSD, trovi a compilare (compresi librerie, programmi vari eccetera) decine di migliaia di file (sembra paradossale, ma perfino vim, sì vim, quindi l'editor testuale, ha migliaia e migliaia di file-dipendenze, tanto che normalmente si usa vim-lite).

    Lì vedi subito cosa succede: il caos. Librerie di versioni differenti, incompatibili, linkate male, blocco per versioni tra le più diverse e così via (magari pure incompatibilità sottili e devastanti tra clang\lvmm e gcc, o magari tra gcc "normale" e la versione 4.9, nonostante tutti i pre-test)

    Insomma, compilare "di grosso" programmi C/C++ non è un affare banale, per nulla, cosa mooolto diversa dai "programmini" che normalmente si è abituati a maneggiare.

    Se (per esagerare) apache fosse un singolo filettone, non ci sarebbe nessun problema a compilarlo, basterebbe aspettare il termine.

    D'altronde se devi invece compilare un megaprogetto google, che richiede magari giorni o settimane di compilazione (!), la scala è ancora diversa e i problemi anche.
    As always, common sense and good taste should prevail
    A me invece sfugge come risolveresti il problema delle librerie incompatibili usando 1 (o comunque pochi) file invece dell'approccio tradizionale. Se nell'approccio classico devi ricordarti di linkare le librerie della versione giusta, nel tuo caso non devi forse ricordarti di copia-incollare le funzioni della giusta versione della libreria nel mega file? In pratica sposti il problema a monte.

    Comunque, la differenza tra leggere X righe in K o M file è la stessa che c'è tra mettere tutti i file di un file system in un'unica cartella o suddividerli per utente, categorie ecc.. Poi sono d'accordo che esistano le esagerazioni, tipo java che richiede un file per ognitipo pubblico, anche quando si tratta di poche righe (anche se ora con le espressioni lambda è leggermente meglio).
  • Re: [C] Strutturazione programma a più moduli

    I miei stessi programmi non sono certamente monolitici, monofile, ma neppure sono composti da centinaia e centinai di (del tutto inutili) filettini.

    Certamente non esiste LA soluzione (adatta per TUTTI i casi), come dicono i buon googler ci vuole buon senso, evitando atteggiamenti "talebani" del genere "si fa così perchè mi hanno insegnato così (da chi a sua volta tipicamente è stato formato così, risalendo indietro di una 40ina di anni se non più) e quindi sarà giusto così".

    Questo è il messaggio che vorrei far arrivare ai programmatori meno esperti.
Devi accedere o registrarti per scrivere nel forum
15 risposte