Esistono infatti tecniche per semplificare gradualmente il codice e migliorare il design in questo modo. La tecnica generale è conosciuta come "refactoring". Si noti che questo termine è usato sia informalmente (per indicare "qualsiasi cosa che modifica il modo in cui il codice è progettato senza cambiare ciò che fa") e formalmente (per indicare "seguendo una specifica disciplina di refactoring"). Mi riferisco a quest'ultima definizione qui.
In particolare, questo problema è stato molto studiato da Martin Fowler e dal suo libro " Refactoring: Migliorare la progettazione del codice esistente "è uno dei classici libri di ingegneria del software, e vale la pena leggerlo in quest'area.
La tecnica generale suggerita dal libro è:
1) Scrivi test molto dettagliati per la sezione di codice che intendi rifattorizzare.
2) Apporta una piccola modifica specifica al codice. Ad esempio, inline un metodo, rinomina una classe, estrai un codice in un nuovo metodo, estrai una superclasse da una classe esistente, ecc. (Fowler ha elenchi dettagliati di molte piccole trasformazioni nel suo libro, insieme a suggerimenti su come / quando La maggior parte dei nomi delle funzionalità esistenti di "refactoring automatico" come quelle di Eclipse, IntelliJ, ecc. sono state prese da quelle usate nel suo libro. Essenzialmente, sono come "schemi di progettazione" ma sono usati per modificare il codice esistente piuttosto che per progettarlo in primo luogo.)
3) Riesegui i test, per verificare che non hai ancora rotto nulla.
4) Ripeti finché non sei soddisfatto dei risultati.
Quindi, è possibile apportare grandi modifiche al codice accumulando più piccole modifiche, con test tra ciascuna modifica.
Ovviamente, se hai l'abitudine di scrivere e conservare test dettagliati per il tuo codice in primo luogo (una suite di test unitario, una suite di test di regressione, ecc.), il processo sopra descritto sarà molto più facile che se tu debba scrivere i test immediatamente prima di iniziare il refactoring. Inoltre, sarà molto più facile farlo se la parte della tua suite di test che stai rieseguendo tra ogni modifica è in grado di funzionare abbastanza rapidamente.
Nota che il codice di refactoring in questo modo è una DISCIPLINE. Non è la stessa cosa che circola casualmente cambiando codice. Il frequente test durante il processo è essenziale per garantire che eventuali modifiche involontarie apportate al comportamento del programma vengano rilevate rapidamente, mentre è ancora possibile ricordare ciò che hai fatto. Per questo motivo, spesso è anche una buona idea eseguire il refactoring separatamente da altri sviluppi che aggiungono o modificano il comportamento del programma, poiché tali tipi di modifiche potrebbero invalidare i test esistenti. Potresti, ad esempio, alternare fasi: aggiungere una funzione, quindi rifattorizzare un bit, quindi aggiungere un'altra funzionalità, quindi rifattorizzare un po 'di più, quindi correggere un bug, quindi refactoring, ecc.
Se sei coerente nella programmazione usando queste tecniche per semplificare il tuo codice, la tendenza generale del tuo codice nel tempo sarà che diventerà via via più semplice e più facile da leggere, piuttosto che al contrario (che è, purtroppo, più comune in industria).
Potresti anche scoprire che alcune delle comunità attorno alle metodologie di sviluppo del software Agile e / o XP possono essere utili su come / quando / che cosa da rifattorizzare, poiché il refactoring continuo in questo modo è considerato una caratteristica necessaria di molte di queste metodologie .
Ho visto molti progetti diventare gradualmente così croccanti e complicati che nessuno li ha capiti e alla fine dovettero essere scartati, perché il loro mantenimento alla fine richiedeva più sforzi di quanto avrebbero fatto la riscrittura. Il refactoring è un modo per evitare questo problema.