Come evitare la dipendenza binaria dalla modifica della dimensione

2
class A { public: int i; }; // A.h and defined in project libA.vcxproj (libA.dll)

Sto usando la classe A in più posti in vari progetti come di seguito. Circa 100 progetti.

include "A.h"
class UseA { public: A *a; UseA(){ a = new A(); } ~UseA() {delete a;} }

Il mio problema è ogni volta che aggiungo una variabile membro alla classe A dovrò costruire tutti i progetti (~ 100) poiché la dimensione della classe A è stata cambiata e costruire 100 progetti richiede molto tempo.

Come evitare di creare così tanti progetti sulla modifica delle dimensioni di una singola classe? Inoltre ho molte classi come la classe A definita in libA.vcxproj.

    
posta user3136061 26.12.2013 - 08:53
fonte

3 risposte

5

Hai familiarità con l' idioma PIMPL ? Per alcuni casi, può risolvere questo problema esatto. La versione breve è che si avvolgono tutte le variabili dei membri privati in un puntatore opaco a un tipo, in modo che quando si aggiunge un nuovo membro privato non sia necessaria la stessa ricompilazione ...

    
risposta data 26.12.2013 - 09:23
fonte
5

Prima assicurati di averne veramente bisogno: avere una libreria centrale che viene riutilizzata più di 100 volte funziona meglio quando l'interfaccia pubblica di quella libreria non cambia troppo spesso o solo in momenti specifici nel tempo. Controllare se è possibile suddividere la libreria in parti più piccole, in modo che le modifiche in una parte non influiscano sui progetti dipendenti delle altre parti. Controlla anche se è possibile sviluppare prima eventuali modifiche a quella libreria "in privato" e pubblicarle (visibilmente per la maggior parte dei progetti dipendenti) solo per le nuove "major release" di quella libreria.

Ma supponiamo che le dipendenze del progetto siano corrette e necessarie per il tuo sistema, e hai davvero bisogno di estendere le parti pubbliche di quella libreria centrale (o della classe centrale "A") molto spesso. Quindi, non è possibile evitare che tutti i progetti dipendenti debbano essere ricompilati. Ma poiché in genere non si apportano modifiche a tutti i 100 progetti contemporaneamente, non è necessario ricompilarli tutti sulla stazione di lavoro locale .

Ciò di cui hai bisogno in questa situazione è un < strong> build server - un server che controlla automaticamente tutte le modifiche dal tuo SCCS ed esegue una compilazione completa di tutti i 100 progetti in background. Per configurare un sistema di questo tipo, è necessario anche un buon processo di compilazione automatico . Spero che i tuoi 100 progetti possano essere suddivisi in gruppi di progetti che possono essere compilati e testati singolarmente, altrimenti devi prima risolvere il problema.

Anche una buona lettura, anche se un po 'obsoleta: Progetto software su larga scala in C ++ di John Lakos . Questo libro spiegherà anche l'idioma PIMPL citato da Jtrana in modo approfondito, anche se questo ti aiuterà solo con le parti private delle tue lezioni, non con quelle pubbliche come nel tuo esempio.

    
risposta data 26.12.2013 - 09:36
fonte
4

Oltre alle risposte di Doc Brown e J Trana .

  • La risposta di Doc Brown sottolinea che la ricostruzione di tutto il progetto è molto necessaria nello sviluppo del software; quindi cerca di ridurre il dolore usando l'automazione build, invece di evitarlo.

  • La risposta di J Trana è una forma di incapsulamento o nascondere le informazioni . Se la maggior parte degli utenti della classe A non ha bisogno di accedere al nuovo membro, è possibile seguire questi passaggi:

    • Rendi il nuovo membro privato
    • Inserisci il nuovo membro all'interno di un membro secondario privato della classe A e inizializzalo nel costruttore di A.
    • Fornire metodi di accesso (getter e setter) per il nuovo membro.
    • Si noti che questo richiede ancora la ricostruzione dell'intero progetto, perché in C ++ qualsiasi modifica in un file di intestazione avrà richiesto una ricostruzione.
  • Il mio suggerimento n. 1 (specifico del fornitore)

    • Alcuni compilatori C ++ hanno opzioni per migliorare le prestazioni del processo di compilazione.
    • Esempi: "build incrementale", "build con più processi" ecc.
  • Il mio suggerimento n. 2:
    Se devi davvero ridurre il tempo speso per la ricostruzione mentre esegui molte piccole modifiche sperimentali che coinvolgono nuovi membri, prendi in considerazione la conversione dei membri dei dati in un pacchetto di proprietà .

    • Un sacchetto di proprietà è un dizionario ( std :: map ) da valori stringa a varianti.
    • Se la classe A fornisce metodi get / set per questo dizionario, l'aggiunta e la rimozione di nuove chiavi non richiederà una ricostruzione.
    • Tuttavia, gli svantaggi sono:
      • Sarà molto più lento leggere e scrivere sui valori nel dizionario, rispetto all'accesso a un membro della classe.
      • L'intero progetto sarà più soggetto a errori, perché il compilatore non sarà in grado di eseguire controlli del nome e controlli di tipo sulle chiavi e sui valori memorizzati in un sacchetto di proprietà.
      • Esempio:
        Un compilatore può intercettare il bug in cui si tenta di accedere a un membro della classe che non esiste.
        Un compilatore non rileva automaticamente il bug in cui si accede a una chiave del dizionario che non esiste. Il programmatore deve scrivere il codice per gestire questa situazione.
risposta data 26.12.2013 - 12:26
fonte