Come dovrei iniziare a refactoring la mia applicazione C ++ per lo più procedurale?

6

Abbiamo un programma scritto in C ++ che è per lo più procedurale, ma usiamo alcuni contenitori C ++ dalla libreria standard (vettore, mappa, elenco, ecc.). Apportiamo continuamente modifiche a questo codice, quindi non lo chiamerei un pezzo stagnante di codice legacy che possiamo semplicemente concludere.

Ci sono molti problemi con questo codice che rende sempre più difficile per noi apportare modifiche, ma vedo che i tre problemi principali sono:

  1. Molte delle funzioni fanno più (molto di più) di una cosa
  2. Violare il principio DRY a sinistra ea destra
  3. Abbiamo variabili globali e lo stato globale fino alla wazoo.

Stavo pensando che dovremmo prima attaccare le aree 1 e 2. Lungo la strada, possiamo "de-globalizzare" le nostre funzioni più piccole dal basso verso l'alto passando in informazioni che sono attualmente globali come parametri per le funzioni di livello inferiore dalle funzioni di livello più alto e quindi concentrarsi su come eliminare la necessità di variabili globali il più possibile.

Ho appena finito di leggere Code Complete 2 e The Pragmatic Programmer, e ho imparato molto, ma mi sento sopraffatto. Vorrei implementare il test delle unità, passare da un approccio procedurale all'approccio OO, automatizzare i test, utilizzare un sistema di registrazione migliore, convalidare completamente tutti gli input, implementare una gestione degli errori migliore e molte altre cose, ma so se iniziamo tutto ciò in una volta, ci rovineremmo. Penso che i tre che ho elencato siano i più importanti per iniziare.

Qualsiasi suggerimento è benvenuto.

Siamo un team di due programmatori per lo più con esperienza nello scripting in-house. Sarà difficile giustificare il tempo dedicato al refactoring, soprattutto se non possiamo fatturare il tempo a un cliente. Che ci crediate o no, questo progetto ha avuto successo abbastanza da tenerci occupati a tempo pieno e anche da diversi consulenti impegnati ad usarlo per il lavoro dei clienti.

    
posta oob 06.06.2012 - 02:46
fonte

3 risposte

9

Il mio consiglio sarebbe di essere molto molto attento a non rompere qualcosa che funzioni!

Considera questo come un progetto incrementale a lungo termine, migliora il codice nell'area che è rilevante per una richiesta di modifica corrente e, per quanto possibile, lascia il resto da solo.

Non sbarazzarti dei global solo perché sono globali. Alcuni dati sono naturalmente globali: ora del giorno, numero di esecuzione, data di lavoro, stato della connessione, spegnimento richiesto ecc.

Il principio DRY si applica principalmente allo sviluppo, una volta che il codice è stato ripetuto, fa poca differenza finché non è necessario apportare una modifica importante al codice ripetuto. Quindi lascia questa roba da sola fino a quando non richiede un grande cambiamento.

Molte funzioni che fanno più di una cosa. -- benvenuto nel mondo reale. I requisiti aziendali sono mai semplici come quelli che vedi nei libri di testo e sono spesso un amalgama di complesse funzionalità interdipendenti. Se vedi un caso in cui una funzione può essere suddivisa in modo pulito in due funzioni semplificate separate, salta su di essa, ma non aspettarti di trovarne troppe.

    
risposta data 06.06.2012 - 03:50
fonte
7

Vorrei iniziare con il problema n. 3 prima. È ottimo per refactoring le tue funzioni per evitare DRY e SRP, ma quando devi refactoring di nuovo per affrontare sbarazzarsi dei globali, non è molto importante. Se passi semplicemente un int a ogni funzione del tuo programma, non è affatto diverso dal reale stato globale. È necessario creare solide interfacce e incapsulamento. Inoltre, è piuttosto difficile rifattorizzare qualsiasi funzione che abbia una dipendenza globale.

Il trucco qui sta per essere, isolare un gruppo di funzioni correlate e rifattorizzarle fino a quando non sono di alta qualità, e poi tornare su un altro gruppo. La chiave qui è di rompere le loro interfacce in modo da poterle poi ridefinire individualmente, se necessario.

Per una migliore gestione degli errori, l'uso corretto delle classi e delle eccezioni lo porterà automaticamente, per così dire.

Inoltre, creerei un nuovo design per il programma da zero e lo aggiusterò, in modo che il risultato finale non sia un pasticcio di moduli tutti codificati individualmente ma che non hanno senso come gruppo.

Il refactoring può essere espresso al meglio come un pagamento del debito tecnico accumulato quando il programma è stato creato per la prima volta- in altre parole , in futuro, dovrai comunque fare questo lavoro per implementare alcune funzionalità o correggere qualche bug. A lungo termine, stai risparmiando tempo e denaro.

    
risposta data 06.06.2012 - 03:27
fonte
6

Per prima cosa, cerca di eliminare tutti gli avvisi nella compilazione del tuo programma. Assicurati di compilare qualcosa come il -Wall flag. Eliminare gli avvisi è un problema comunemente trascurato che richiede attenzione.

Successivamente, prova a mettere le mani su un analizzatore statico C ++ . L'esecuzione dell'analizzatore statico sul tuo codice genererà un elenco di problemi con il tuo codice e molto spesso i problemi verranno ordinati in base alla gravità. Cerca di risolvere prima le violazioni più gravi e utilizza l'analizzatore statico per guidare il tuo refactoring.

    
risposta data 06.06.2012 - 02:52
fonte

Leggi altre domande sui tag