Come evitare i metodi di colla gigante?

21

Nel mio attuale lavoro, sono stato incaricato di ripulire il vecchio codice alcune volte. Spesso il codice è un labirinto e i dati dietro di esso sono ancora più intricati. Mi trovo a pettinare le cose in modi piacevoli, ordinari e modulari. Ogni metodo fa una cosa e lo fa bene. Questo è quando le cose iniziano a andare a sud ...

Invariabilmente, finisco con un'API pulita e nessun vero modo di legare tutto insieme. La soluzione è stata quella di scrivere un brutto metodo "colla" (generalmente pieno di dichiarazioni condizionali) che alla fine richiama tutti i miei metodi "puliti".

Il metodo della colla di solito finisce per essere una versione concisa del groviglio di codice / dati che stavo cercando di ripulire. In genere è più leggibile, ma è comunque fastidioso.

Come posso evitare tali metodi? Si tratta di un sintomo di dati intricati o di un riflesso di qualcosa che sto facendo male?

    
posta cmhobbs 27.02.2013 - 06:33
fonte

5 risposte

12

Ti darò la nostra esperienza refactoring LedgerSMB. Abbiamo preso la decisione di fare le cose in modo diverso all'inizio e stiamo ancora facendo esattamente quello che descrivi ma senza molti metodi di incollaggio (abbiamo alcuni metodi di incollaggio, ma non molto).

Vita con due Codebase

LedgerSMB è sopravvissuto con due codebase per circa 5 anni e sarà diverso ancora prima che il vecchio codebase venga eliminato. Il vecchio codebase è un vero orrore da vedere. Bad db design, Perl costruisce come IS->some_func(\%$some_object); insieme al codice che mostra esattamente il motivo per cui la metafora degli spaghetti viene talvolta usata (percorsi di esecuzione che si snodano tra moduli e back, e tra lingue, senza rima o motivo). Il nuovo codebase lo evita spostando le query db in stored procedure, con un framework più pulito per la gestione delle richieste e molto altro ancora.

La prima cosa che abbiamo deciso di fare era provare a refactoring modulo per modulo. Ciò significa spostare tutte le funzionalità in un'area specifica in un nuovo modulo e quindi agganciare il vecchio codice nel nuovo modulo. Se la nuova API è pulita, questo non è un grosso problema. Se la nuova API non è un problema, è un invito a lavorare un po 'di più sulla nuova API ....

La seconda cosa è che ci sono molte volte in cui il nuovo codice deve accedere alla logica nel vecchio codice. Questo deve essere evitato nella misura del possibile perché porta a metodi di incollaggio che sono brutti ma non sempre è possibile evitarlo. In questo caso i metodi di colla dovrebbero essere minimizzati ed evitati nella misura del possibile ma usati quando necessario.

Per fare questo lavoro devi impegnarti a riscrivere le funzionalità tutte in un'area specifica. Se è possibile, ad esempio, riscrivere tutto il codice di tracciamento delle informazioni dei clienti in una sola volta, significa che il codice che chiama questo dal vecchio codice non è difficile da utilizzare e l'invio al vecchio codice dal nuovo codice è ridotto al minimo.

La seconda cosa è che se hai astrazioni ragionevoli al tuo posto, dovresti essere in grado di scegliere quale livello dell'API chiamare e come mantenerlo pulito. Tuttavia, dovresti pensare a riscrivere le parti che chiamano la tua API in modo che siano anche un po 'più pulite.

Esistono molte aree di strumenti aziendali irriducibilmente complessi. Non puoi liberarti di ogni complessità. Ma puoi gestirlo concentrandoti sulle API pulite che fanno specificamente ciò che devi fare e sui moduli che utilizzano questa API in modo costruttivo. La colla dovrebbe essere l'ultima risorsa solo dopo aver considerato che la riscrittura del resto del codice chiamante potrebbe essere più veloce.

    
risposta data 27.02.2013 - 07:13
fonte
8

Sembra che quello che hai fatto sia preso da una confusione di un precedente codebase e creato un codebase modulare precedente

.

Invariably, I end up with a clean API and no real way to tie it all together. The solution has been to write a big ugly "glue" method (generally full of conditional statements) that eventually calls all of my "clean" methods.

Con codice procedurale (anche se è camuffato da OO), finirai sempre con qualche tipo di flusso di lavoro sequenziale definito da qualche parte, spesso pieno di complessi rami condizionali come descriveresti. Sospetto che sia questa natura procedurale del codice che ti fa sentire che qualcosa non va. Questo non è necessariamente un aspetto negativo e quando si lavora con codice legacy potrebbe essere del tutto inevitabile

    
risposta data 27.02.2013 - 12:04
fonte
6

Dovresti ripulire il metodo della grossa colla brutta nello stesso modo in cui hai ripulito il codice originale. Suddividilo in modo ordinato e modulare. Probabilmente hai gruppi di linee di codice che eseguono alcune attività suddividendo queste linee in metodi, se condividi alcune variabili potresti prendere in considerazione l'inserimento delle variabili condivise e dei nuovi metodi in una classe.

    
risposta data 27.02.2013 - 10:29
fonte
1

Fondamentalmente, continui ad aggiungere livelli di astrazione, fino a quando non appare proprio su ogni livello preso da solo . La cosa paradossale dell'astrazione è aggiungere complessità per ridurlo, perché quando leggi il codice astratto, ti interessi solo con uno strato alla volta. Se ogni livello è abbastanza piccolo da essere facilmente compreso, non importa quanti strati si posano sopra.

Questo è anche ciò che rende le astrazioni difficili da scrivere. Anche qualcosa di semplice come una matita è piegato alla mente se cerchi di tenere tutti i suoi strati di astrazione nella tua testa a una volta. La chiave è ottenere un livello nel modo che preferisci, che hai fatto, quindi dimenticare tutta la complessità che sottende quel livello e fare la stessa cosa al livello successivo.

    
risposta data 27.02.2013 - 17:37
fonte
0

Sembra che tu stia rifattorizzando l'API semplicemente pensando all'implementazione dell'API, ma senza pensare abbastanza al codice che usa l'API, cioè al "codice colla" di cui stai parlando.

Se è vero potresti provare a iniziare dall'altra parte. Riscrivi le cose che rischiano di diventare il tuo brutto codice collante e crea un paio di interfacce non ancora implementate che diventeranno la tua API in quel processo. Non pensare ancora troppo all'implementazione effettiva di questa API: va bene se hai la sensazione che tu possa farlo. E solo allora riscrivi il codice labirinto per conformarti a quell'API. Ovviamente ci saranno alcuni cambiamenti nell'API e il codice della colla in questo processo, ma dovrebbe adattarsi meglio.

    
risposta data 04.03.2013 - 20:44
fonte