Come prevenire i problemi a valle dovuti all'ereditarietà

7

L'ho spostato da Stack Overflow e questo era il posto suggerito da chiedere. Questo è stato contrassegnato come possibile duplicato di una domanda sul merito della composizione sull'ereditarietà . Non sto facendo questa domanda, sto cercando strategie per gestire lo sviluppo dato il codice che abbiamo.

Il contesto della domanda è un insieme di applicazioni scritte in C ++ con Qt. Lavoriamo in modo pseudo agile, cioè abbiamo scatti di 2 settimane ma non abbiamo rilasci frequenti.

Sono tutte variazioni di un tema, ma ognuna modifica quella precedente.

Questo non è uno scenario ideale ma con cui devo lavorare.

Quindi l'applicazione A usa Alib. l'applicazione B usa Blib e Alib; la maggior parte delle classi in Blib sono discendenti di quelli in Alib. Allo stesso modo l'applicazione C usa Alib Blib e Clib, che sottoclasse principalmente da Blib ma anche occasionalmente da Alib.

Usiamo CVS ed è un vero e proprio dolore al collo ramificare le nostre build in quanto i progetti MSVC non si fondono mai correttamente.

Ciò che accade attualmente è che uno sviluppatore che lavora su Alib può causare problemi imprevisti sia in Blib che in Clib a meno che non adottiamo alcune strategie per la revisione o regole sullo sviluppo.

Abbiamo molta pressione sul tempo e al momento non abbiamo il tempo di riorganizzare il codice, quindi sono alla ricerca di cose che possiamo fare nel quadro attuale.

Se usassimo git sarebbe più semplice suddividere il codice per ogni dev, ma di nuovo non ci siamo ancora al momento (è nella pipeline).

Sto pensando lungo la linea di richiedere tutti i nuovi sviluppi che alterano (al contrario di aggiungere) la funzionalità in ALIB per sottoclasse tale comportamento.

Altre opzioni di cui ho letto includono "fallire spesso", cioè essere sfacciati nel commettere / cambiare le cose in Alib e assicurarsi che Blib e Clib siano rivisti abbastanza spesso da tenere il passo con le modifiche.

Simile a questo è frequente revisione del codice (uno sviluppatore (io) ha una buona conoscenza di tutte e tre le librerie quindi dovrebbe essere in grado di individuare i potenziali effetti downstream in anticipo), che pone la domanda prima o dopo il commit.

Modifica: Grazie per l'ampia gamma di soluzioni, vorrei poter contrassegnare un paio di queste come risposte, ma sono andato con la risposta di John Wus. Ha articolato il mio dilemma abbastanza bene nel terzo punto - cercando di ridurre la ripetizione di noi stessi (cioè non violiamo DRY) pur avendo un certo isolamento per ogni lib. In ultima analisi, un refactor del codice è in ordine, ma più (alcuni!) Test unitari dovrebbero evidenziare il codice rotto. Uno dei problemi che abbiamo riscontrato è che lo sviluppatore di Alib avrebbe visto le loro modifiche influenzare Blib e Clib e andare a modificarle in modi che gli sviluppatori di Blib e Clib non apprezzavano esattamente. Quindi una regola sul mantenimento del codice chiuso (estendere ma non modificare) è anche molto pertinente.

    
posta mike 04.10.2016 - 16:02
fonte

3 risposte

3

Tre opzioni per te

Segui il Principio Aperto / Chiuso

Da un punto di vista del codice e della gestione dei processi, ottenere un accordo di gruppo per aderire al principio aperto / chiuso dovrebbe aiuta a risolvere il problema.

Se sei in grado di convincere tutti a seguire questo principio in modo abbastanza rigoroso, potrebbe essere tutto ciò che devi fare.

Integrazione continua basata su test unitari automatizzati

Sviluppa un processo di compilazione continuo automatizzato in cui ALib, BLib e CLib vengono creati ogni volta che uno di essi cambia.

Sviluppa una suite di test unitari automatizzati eseguiti come parte del costruire. Se uno dei test fallisce, la compilazione dovrebbe fallire.

Fai pubblicamente vergogna a chiunque rompa la build .

Utilizza le interfacce invece

Se non puoi aiutare te stesso e ALib deve essere in grado di essere modificato continuamente, allora forse dovresti allontanarti dall'ereditarietà dell'implementazione e attenersi strettamente a ereditarietà dell'interfaccia , come segue:

  1. Sviluppa una nuova lib, chiamala ILib . Questa libreria dovrebbe contenere zero codice di implementazione e dovrebbe contenere solo definizioni di interfaccia.
  2. Rimuovi la relazione di ereditarietà tra ALIB, BLib e CLIB
  3. Aggiungi una relazione di interfaccia tra ALib- > ILib, BLib- > ILib e CLib- > ILib
  4. Blocca ILib

In questo modo, qualsiasi modifica di implementazione in ALib avrà un impatto zero su BLib e CLib.

Lo svantaggio è che potresti finire per duplicare un sacco di codice, ovvero violare ASCIUGARE .

    
risposta data 05.10.2016 - 01:09
fonte
2

È improbabile che trovi un proiettile d'argento, temo. Hai tutti i sintomi del problema della classe base fragile .

A breve termine, concentrerei il massimo sforzo possibile per ottenere un ambiente di sviluppo e la copertura del test e ottenere la copertura del test più ampia possibile. In questo modo, almeno attenuerai il problema se non lo elimini.

Un'idea strutturale che potresti studiare è provare ad avere l'applicazione A non usare direttamente Alib ma sottoclassi in A'lib. Potrebbe non essere OOP puro ma, se la funzionalità di cui hai bisogno per l'app A non è effettivamente necessaria per B e C, puoi inserirla in A'lib e mitigare parte della fragilità.

Buona fortuna. Sono stato nei tuoi panni e non è stata l'esperienza più piacevole.

    
risposta data 04.10.2016 - 17:39
fonte
2

a developer working on Alib can cause unforeseen issues in both Blib and Clib

Sembra che non ci siano troppi o meno test automatici per il tuo Alib, e troppo pochi per le tue altre libs. Se uno sviluppatore cambia qualcosa in Alib che si aspetta di essere compatibile verso l'alto, i test dovrebbero assicurarsi che la funzionalità esistente non venga infranta. E se la modifica è intenzionale incompatibile, solo la serie di test prevista dovrebbe interrompersi.

Questo è ciò su cui dovresti lavorare - automatizza gran parte del tuo processo di revisione manuale usando i test.

    
risposta data 04.10.2016 - 22:17
fonte

Leggi altre domande sui tag