Quando refattorizzare


32

Ho letto la maggior parte del libro di Refactoring di Fowler e ho refactored molte applicazioni nel mio passato grandi e piccole.

Una delle cose più difficili che trovo ad insegnare è "quando" rifattorizzare. Tendo a farlo basandomi su un istinto che in passato mi è servito molto bene. Tuttavia, quando si discute con la gente sul fatto che un pezzo di codice debba essere lasciato solo o refactored in questo momento, è difficile sostenere il "controllo dell'intestino".

Sento che dovrebbero esserci approcci più rigorosi a questo, ma non sono sicuro di cosa siano.

Capisco "odori di codice", refactor rosso-verde e altri pensieri, ma spesso sento che il momento migliore per refactoring non è la prima volta che scrivi il codice, ma la seconda o la terza volta che usi il codice e ti rendi conto che in realtà è un problema ed è attualmente in uso.


2
In sostanza, stai chiedendo la stessa cosa di questo: programmers.stackexchange.com/questions/6268/… . Tranne che la soglia per agire è più bassa, dal momento che il costo e il rischio sono inferiori, giusto?
S. Lott,

Risposte:


22

Rifattore quando il costo del refactoring è inferiore al costo del non refactoring.

Misura "costo" come puoi. Ad esempio, il codice è implementato così male che i bug banali costano ore o giorni per essere risolti? Il refactoring ti consentirà di acquisire più clienti o aumentare la capacità o migliorare le prestazioni e rendere così più felici i tuoi clienti esistenti?


shortform and perfect
ZJR

8
In altre parole: "vale la pena refactoring quando vale la pena refactoring". Duh. Beh, non è proprio una risposta, vero :) Measure "cost" however you can.- OK, come? Non è questo il nocciolo della domanda? Quale prospettiva temporale dovrebbe essere applicata quando si misura quel costo?
Konrad Morawski,

2
@Morawski: no, è una parafrasi errata. Ho detto che vale la pena refactoring se il valore ricevuto dal refactoring è maggiore del costo del refactoring. Non è lo stesso che dire "vale la pena refactoring quando vale la pena refactoring". Calcola il costo del refactoring. Calcola il costo del non refactoring. Qual è più grande?
Bryan Oakley,

@BryanOakley: il problema è che non puoi "calcolare" questi costi. Puoi al massimo stimarli, il che è davvero difficile da fare quando si tratta del costo del non refactoring . Quale moltiplicatore dei costi di manutenzione applichi alla versione non riformata rispetto alla versione rifattorizzata? Come fai a sapere se il codice in questione dovrà essere mantenuto o modificato? Come stimare il numero di bug che genererà? Alla fine immagino che tutti inconsciamente facciamo questo tipo di stime come parte del nostro processo decisionale quando pensiamo al refactoring, ma non ci si può aspettare precisione da esso.
guillaume31,

1
@ ian31: vero, non puoi calcolare i valori e il meglio che puoi fare è stimare. Tuttavia, questo è l'unico modo veramente valido per decidere se effettuare il refactoring o meno, supponendo che il tempo e le risorse siano limitati. Devi decidere se ne vale la pena. Il modo in cui definisci "valore" è una scienza molto inesatta. Il punto è che non dovresti riflettere su una sensazione viscerale - ci dovrebbe essere una buona ragione per fare il refactoring oltre a "Voglio che il codice sia più carino".
Bryan Oakley,

12

  1. La complessità ciclomatica della funzione è inferiore a 5?
  2. Hai capito completamente quale complessità ciclomatica era senza seguire quel collegamento?
  3. Hai un test automatizzato o un test case documentato per ogni percorso attraverso la funzione?
  4. Passano tutti i casi di test esistenti?
  5. Puoi spiegarmi la funzione e tutti i casi limite in meno di 1 minuto?
  6. In caso contrario, che ne dici di 5 minuti?
  7. 10 minuti?
  8. Ci sono meno di 100 righe di codice nella funzione (inclusi i commenti)?
  9. Riesci a trovare altri due sviluppatori che concordano sul fatto che questo codice è privo di errori solo tramite ispezione visiva?
  10. Questa funzione è utilizzata in un solo posto?
  11. La funzione soddisfa i suoi obiettivi prestazionali (tempo / memoria / CPU)?

punteggio

Aggiungi le risposte "no" sopra:

  • 0-1 - Perché dovresti pensare di refactoring? Probabilmente vuoi semplicemente rinominare le variabili perché non ti piace la convenzione di denominazione dello sviluppatore precedente
  • 2-5 - Potrebbe essere necessario modificare leggermente, ma non terrei una versione di produzione per qualcosa in questa gamma
  • 6-8 - OK, probabilmente dovremo risolvere questo problema ... È probabile che continueremo a rivisitare questo e / o in realtà non sappiamo cosa sta facendo. Ancora sul recinto, ma è altamente sospetto
  • 9+ - Questo è un candidato principale per il refactoring. (Nota, la scrittura di casi di test è una forma di refactoring)

http://mikemainguy.blogspot.com/2013/05/when-to-refactor-code.html


4
# 2 suona molto snob ed è in realtà inutile per la valutazione del codice . # 3 e # 4 non tutte le società utilizzano test unitari. # 8 Evita i commenti ove possibile e 100 righe sono troppo alte. Ho 1 grande monitor widescreen in modalità verticale e sarei a malapena in grado di vedere l'intera funzione contemporaneamente. Se sono più di 15 righe di codice effettivo, dovrebbe esserci già una solida ragione per mantenerlo in questo modo. È un approccio pratico e pratico avere una lista di controllo, ma troppi punti qui sono solo inventati o usano valori casuali senza alcun ragionamento.
R. Schmitz,

8

Quando il tuo istinto ti dice che probabilmente dovresti fare un po 'di refactoring, è probabile che il tuo istinto ti dica un po' tardi che hai rimandato qualcosa di importante per troppo tempo.

Capisco "odori di codice", refactor rosso-verde e altri pensieri, ma spesso sento che il momento migliore per refactoring non è la prima volta che scrivi il codice, ma la seconda o la terza volta che usi il codice e ti rendi conto che in realtà è un problema ed è attualmente in uso.

Esistono effettivamente due livelli di refactoring. Il primo sono gli ovvi problemi che compaiono al primo codice. Queste sono le piccole ottimizzazioni che ti costano molto poco da fare in anticipo. Cose come mantenere piccoli i metodi e le classi e aderire a DRY e SRP. Quindi hai la fase aggiuntiva di gestire i principali difetti nel tuo design, che potrebbe non essere immediatamente evidente fino a quando il tuo codice ha un paio di miglia sotto di esso. È di questo secondo livello di cui stai parlando, e tuttavia per garantire che il refactoring successivo non sia troppo costoso, devi aver già scritto il tuo codice in modo tale che lo sforzo che in seguito pensi sia reso più semplice e meno costoso, il che significa fare un refactoring anticipato.

Come ha detto Jeff nella sua risposta, "il tempo è denaro" , in particolare nelle aziende in cui il carico di lavoro è elevato e i rischi sono ancora più elevati. Il tempo speso in anticipo per assicurarsi che il codice sia nel suo stato migliore possibile è tempo risparmiato in seguito, quando prendere in giro quello che avrebbe dovuto essere un semplice refactoring risulta essere un'operazione importante.

Quando si scrive un software, ogni momento speso per migliorare il codice in anticipo viene risparmiato tempo in seguito, quando ne avrai davvero bisogno. Prima fai il refactoring, più chiare saranno le tue modifiche successive. È come effettuare un acconto in dollari di oggi contro il debito tecnico futuro che sarà in dollari gonfiati di domani.

In ogni caso, il refactoring non dovrebbe essere un compito che rimandare a qualche misterioso futuro quando il software è già completo e stabile, poiché aumenta i rischi in seguito quando la posta in gioco è molto più alta e il prodotto molto più difficile da cambiare. Il refactoring dovrebbe essere una parte delle tue attività quotidiane e questa è l'essenza della filosofia Red-Green-Refactor che hai citato.


2

Penso che la tua domanda possa rispondere in modo diverso da ogni sviluppatore e persino dal management responsabile della programmazione.

La mia preferenza personale è che, ogni volta che apprendo qualcosa di nuovo, o perfeziono le mie migliori pratiche, rifletto il codice che posso - mi piace mantenere il mio codice allo standard non appena apprendo quale sia lo standard migliore da utilizzare per quella situazione. Mi è permesso farlo, però, perché è una società più piccola che utilizza lo stesso software per lunghi periodi di tempo.

In una società di sviluppo software più grande in cui il tempo è denaro, potrebbe essere solo per iniziare a progettare con le migliori pratiche che hai imparato da questo punto in poi, non preoccuparti del refactoring fino alla versione 2 di quel software specifico?

Sento che insegnare quando il refactoring dipende davvero dalla compagnia in cui ti trovi attualmente.


2

"Quando refactoring?"

Risposta breve: ogni volta che incontri un codice che ha un cattivo odore o potrebbe essere migliorato ( regola del boy scout )

In pratica, questo succede:

  • Se pratichi TDD, sistematicamente durante la fase Refactor del ciclo TDD, cioè quando il test è verde e prima di iniziare a scrivere un nuovo test.
  • Come risultato di una revisione del codice
  • Quando si rileva il codice legacy
  • Quando si consuma codice che sembra progettato in modo strano
  • eccetera.

Sento che questo dice semplicemente "Dovresti rifattorizzare" senza rispondere alla parte più difficile: "Sento che dovrebbero esserci approcci più rigorosi a questo, ma non sono sicuro di cosa siano."
Orrore

Non so cosa dire se non sentire ciò che è doloroso da mantenere, annusare odori di codice e usare la tua esperienza. Dubito che ci sarà mai un metodo definito e definitivo che ti dice quando e cosa refactoring se è quello che stai cercando.
guillaume31,

1

Quando ho appreso per la prima volta il refactoring, il mio mentore mi ha detto: "Fallo due volte, tieni il naso. Fallo tre volte. Rifattore." (Grazie, Josh!) Per essere precisi, quello che stava dicendo era che quando stai per scrivere lo stesso blocco di codice per la terza volta (o anche un modello di codice simile), quello è il momento di refactoring. L'ho seguito negli ultimi 10 anni e l'ho trovato una regola empirica abbastanza solida.

L'uso di Eclipse, o IDE simile che ha un forte supporto per il refactoring, riduce lo sforzo per eseguire il refactoring. Il supporto IDE rende più probabile il tuo refactoring non appena tocchi la "terza volta" (o vedi la necessità), invece di vederlo come uno sforzo aggiuntivo.

Inoltre, TDD è di grande aiuto anche qui, dal momento che puoi continuare a eseguire i tuoi test come refactor e sapere che non hai rotto nulla.


1

Il refactoring per definizione è un processo. Ciò implica che non dovresti sforzarti di trovare tempo libero per svolgere l'attività di rafactoring, invece dovresti continuare a eseguire il refactoring tutto il tempo quando ti imbatti in un codice di codice che potrebbe essere scritto meglio.

Personalmente mi piace scrivere prototipi evolutivi, dirlo più semplicemente: codice che funziona e quindi riformattare quelli fino a quando non soddisfano gli standard di codifica previsti. Un altro buon esempio è l'aggiunta di funzionalità aggiuntive e il refactoring del codice esistente per consentirne il riutilizzo.


1

Nei miei 20 anni di programmazione, ecco l'unica regola empirica a cui ho effettivamente assistito al lavoro, a cui le persone possono attenersi e ai manager che hanno tempo. (Il refactoring è come una dieta: certo, "calorie in / calorie fuori" è la formula per perdere peso, ma ciò non si traduce in una dieta a cui le persone si conformeranno.) E quindi:

Rifattorizza continuamente, mentre lavori. Usa Test Driven Development in modo da avere diversi cicli di rifattore rosso-verde durante il giorno. Rifattorizza solo le parti del codice che hai toccato.

Una volta che sei più sicuro di te stesso, puoi variare da questo regime.


1

Penso che ciò dipenda dalle esigenze del proprietario del progetto e del ragazzo che risponde per la qualità del codice. Semplicemente non puoi decidere da solo, quando i soldi di qualcun altro sono in discussione.

Per motivi tecnici, ce ne sono diversi.

  • Se hai un bug nel codice, ciò significa che questo posto è frainteso ed è MOLTO probabile che qui possano essere nascosti più errori e sicuramente ci saranno grandi problemi con qualsiasi tentativo di sviluppare le parti collegate del codice. Quindi, questo posto dovrebbe essere controllato per possibili refactoring.
  • Un altro motivo è quando aggiungi o modifichi una funzione e il vecchio codice è molto scomodo per cambiare / aggiungere e le successive modifiche / aggiunte sono altamente possibili. Naturalmente, dovresti bilanciare il costo.
  • Forse il motivo più serio è quando si modifica il codice ed è non verificabile.

Come scrum master, abbiamo avuto uno sviluppatore che ha costantemente sostenuto che ogni storia della squadra era più grande di quanto pensasse il team e abbiamo scoperto che voleva refactificare ogni pezzo di codice che incontrava. Quindi, una storia in 3 punti era sempre un 8 per lui. Chiaramente questo stava rovinando la consegna del valore. Quindi in qualche modo ci deve essere una certa comprensione di quando refactoring e come la decisione dovrebbe essere presa. Solo il mio pensiero, da quell'esperienza (e poche altre).
Curtis Reed,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.