Come rifattorizzare membri statici delle classi base

2

Attualmente sto lavorando al progetto C ++, che può essere classificato come progetto "legacy". Un sacco di codice scritto scadente è stato commesso a causa della mancanza di esperienza e sotto la pressione delle scadenze. Quando provo a correggere i bug, alla fine ne realizzo uno nuovo.

Recentemente ho avuto un po 'di tempo libero e voglio migliorare questo progetto. Per essere precisi voglio iniziare a usare TDD. Tuttavia, si è rivelato non così facile. Ho affrontato il problema che non posso scrivere test per nessuna classe. I singleton sono ovunque. Anche le classi base usano membri statici.

Ad esempio, nel progetto usiamo ampiamente la classe "Numeric" (che è wrapper per la libreria decNumber C per il calcolo decimale). Questa classe ha membri statici per mantenere un contesto (precisione, modalità di arrotondamento, ecc.). È ovvio che ho bisogno di refactoring questa classe per evitare campi statici.

Ho subito pensato all'iniezione di dipendenza e a un modello di fabbrica. La factory manterrà il singolo contesto, ogni classe utente dovrebbe creare istanze numeriche solo usando quella factory. Ma il codice sarà disordinato perché la fabbrica dovrebbe essere iniettata in ogni classe che vuole costruire l'istanza "numerica".

Quale modello posso usare per questo caso? Quale mi fa essere sicuro che ogni istanza della classe "Numeric" utilizza un singolo stato condiviso?

PS: ci sono parallelismi significativi con questa domanda - Dipendenza iniezione ; buone pratiche per ridurre il codice boilerplate .

    
posta fasked 15.12.2013 - 09:59
fonte

2 risposte

2

Mi piace molto il libro Lavorare efficacemente con il codice legacy , di Michael Feathers , per questo scopo. Andrò avanti e non sarò d'accordo con gbjbaanb qui; il test è molto utile per il codice legacy, ma potrebbe essere necessario affrontarlo ad un livello superiore rispetto alle singole classi all'inizio. Inizia scrivendo test funzionali: prendi in giro un oggetto, invialo attraverso il sistema e vedi se esce come previsto dall'altra parte. Questo processo è doloroso, ma necessario.

Una volta eseguito questo tipo di test attorno alle porzioni del codice che si desidera refactoring, è possibile iniziare a fare refactories su larga scala, ad esempio prendendo i metodi statici dalle classi che si stanno testando e quindi iniziare ad espandere l'ambito del tuo refactoring.

    
risposta data 15.12.2013 - 14:54
fonte
1

Dipende da quale piattaforma stai lavorando - Microsoft ha Moles (chiamato qualcos'altro ora) che ti permette di sostituire gli oggetti nel tuo programma con altri oggetti, in modo da poter sostituire i singleton con quelli specifici dei tuoi scenari di test. È meraviglioso e maledettamente più facile da usare rispetto al manomissione del codice per utilizzare le interfacce ovunque, in modo che i sistemi di test unitari inferiori possano funzionare.

Ma generalmente TDD è disapprovato per il codice legacy - come ho detto sopra, quando si scrive codice progettato per essere guidato dai test, bisogna codificarlo in un certo modo. Non facile da usare con la base di codice esistente che non è mai stata scritta in quel modo (il che mi suggerisce che il modo di codifica TDD non è naturale).

Vorrei dimenticare di inserire cose come DI in, poiché renderesti il sistema ancora più complicato e disordinato. È possibile modificare i metodi statici sulla classe, rimuovere la staticità, impostare il costruttore come predefinito e consentire alla classe di impostare proprietà diverse, anche se, se lo statico del numerico è sempre un valore costante, allora qual è il punto in cui lo si cambia ogni oggetto porta lo stato piuttosto che la classe? Solo così puoi usare TDD? Quando lo fai, stai introducendo la più complessità, non di meno.

Per il codice legacy, non esiste una facile via di uscita oltre a dividere le sezioni e tentare di isolarle. Quindi prenditi il tempo necessario per comprendere il resto del sistema. Non c'è un proiettile d'argento qui, dovrai solo sporcarti le mani.

    
risposta data 15.12.2013 - 14:39
fonte

Leggi altre domande sui tag