Come gestisco il refactoring che richiede più di uno sprint?


49

Lavoro con una base di codice di oltre 500.000 righe di codice. Ha un serio bisogno di refactoring. Sono stati identificati sforzi di refactoring che richiederanno più tempo del normale sprint di due settimane. Questi non possono essere suddivisi in compiti più piccoli, come ho visto suggerito in altre risposte su questo sito. Il prodotto deve funzionare al termine dell'iterazione e il refactoring parziale lascerà il sistema in uno stato inutilizzabile poiché la dipendenza tra gli articoli è orribile. Quindi quale sarebbe il modo migliore per affrontare questo ostacolo? Ancora una volta menziono, scomporlo in pezzi più piccoli non è un'opzione, che è già stato fatto.

Aggiornamento: le persone sembrano aver bisogno di una spiegazione del perché questo non può essere inserito in uno sprint di 2 settimane. In uno sprint c'è di più oltre alla semplice scrittura di codice. Abbiamo una politica senza codice senza test. Quella politica non esisteva sempre e gran parte della base di codice non li ha. Inoltre, alcuni dei nostri test di integrazione sono ancora test manuali. Il problema non è che il refactoring stesso sia così grande. È con il fatto che piccole modifiche hanno effetto su molte parti del sistema e dobbiamo assicurarci che quelle parti continuino a funzionare correttamente.

Non possiamo rimandare o estendere uno sprint perché abbiamo aggiornamenti rapidi mensili. Quindi questa modifica che si estende oltre uno sprint non può impedire che l'altro lavoro venga aggiunto all'aggiornamento rapido.

Refactoring vs Redesign: solo perché il nostro processo di sviluppo non è abbastanza efficace per gestire questo refactoring in un ciclo di due settimane non garantisce di rinominarlo in una riprogettazione. Vorrei credere che in futuro potremmo svolgere esattamente lo stesso compito in un ciclo di due settimane man mano che il nostro processo migliora. Il codice in questione non ha dovuto cambiare da molto tempo ed è abbastanza stabile. Ora, man mano che la direzione dell'azienda sta diventando più adattabile al cambiamento, vogliamo che questa parte della base di codice sia adattabile come il resto. Il che richiede il refactoring. Sulla base delle risposte qui, sta diventando evidente che mancano le impalcature necessarie per far funzionare questo refactoring nel lasso di tempo degli sprint normali.

Risposta:

Ho intenzione di seguire l'approccio di diramazione e fusione che Corbin March ha suggerito per la prima volta in modo da poter imparare di più su queste aree problematiche e su come identificare i test mancanti. Penso che andando avanti, dovremmo adottare l'approccio suggerito da Buhb per identificare le aree in cui mancano i test e implementarli prima, quindi eseguire il refactoring. Ci permetterà di mantenere il nostro normale ciclo di sprint di due settimane, proprio come molti hanno affermato che dovrebbe essere sempre il caso del refactoring.


23
Come nota a margine, si tratta per definizione di una riprogettazione su larga scala, non di refactoring . Spero che tu non lo prenda come un pignolo - IMHO è importante usare una terminologia chiara per evitare problemi di comunicazione :-)
Péter Török

9
@Charles, "Il refactoring è in genere fatto a piccoli passi. Dopo ogni piccolo passo, ti rimane un sistema funzionante che è funzionalmente invariato. " Citato dalla pagina che ho linkato sopra.
Péter Török,

2
@Charles: il refactoring può sempre essere eseguito in modo incrementale, mantenendo il sistema funzionante. inserisci un grande commento "Refactoring in progress" nella parte superiore della classe / pacchetto / modulo che viene sottoposto a refactoring e esegui le parti una alla volta. Se tagli una versione temporanea mentre il modello a oggetti è in transizione, va bene.
Sean McMillan,

7
Se stai facendo passi così grandi che non puoi avere un pezzo di codice funzionante su base regolare, questa è la definizione stessa di quando il refactoring diventa riprogettazione. Per favore, non arrabbiarti con le persone per averti chiamato per l'uso improprio della parola. Non c'è niente di sbagliato nel chiedere una riprogettazione. I commentatori stanno semplicemente cercando di indicare che non otterrai le risposte che desideri perché stai abusando della parola, che è ciò che è già successo.
giovedì

5
So che è un po 'fuori tema, ma mi hai reso molto curioso di sapere quali sono le circostanze che rendono impossibile il refactoring a piccoli passi. Si prega di condividere un po 'di più in merito a questo.
Buhb,

Risposte:


14

Se hai il lusso di ritardare il refactoring, ti suggerisco di concentrare le iterazioni in arrivo sull'aggiunta di unit test e test di integrazione automatizzati al punto in cui puoi comodamente refactoring la base di codice, e quindi refactoring in un singolo sprint.


68

Il mio consiglio:

  1. Crea un ramo
  2. Unisci quotidianamente dal tronco al tuo ramo e risolvi i conflitti.
  3. Lavora fino al termine. Il tuo ramo potrebbe essere al di fuori dello sviluppo del core per diversi sprint.
  4. Unisci nuovamente al tronco.

Non si può aggirare il fatto che probabilmente diventerà brutto. Non ti invidio. Nella mia esperienza, quando cambiate drasticamente un progetto, è più facile unire lo sviluppo continuo nel nuovo paradigma rispetto a unire in qualche modo il nuovo paradigma in un tronco ora cambiato dopo che tutto è finito. Tuttavia, farà male.


1
Abbiamo discusso usando questo approccio e se non emergono altre idee prima di affrontarlo, questo è ciò che intendiamo fare.
Charles Lambert,

3
Temo che avrai un sacco di spese generali che si fondono avanti e indietro tra il tronco e il ramo se vuoi eseguire un refactoring così approfondito.
Giorgio,

Nella maggior parte dei casi (si spera) queste modifiche unite non influiranno sul codice in questione qui. Non mi dispiacerebbe estendere la linea temporale per questo cambiamento se assicurasse un risultato affidabile.
Charles Lambert,

1
Considerando la volatilità che la tua presentazione sembra suggerire, forse dovresti prendere in considerazione Git , poiché facilita questo tipo di ramificazione e fusione speculative.
John Tobler,

1
@Giorgio: anche io, l'unione giornaliera sembra un po 'paranoica, ma dipende davvero dalle dimensioni della squadra. Più persone, più modifiche e più frequentemente dovresti unirti. Ogni giorno sembra il limite inferiore, se vuoi avere il tempo di lavorare.
Matthieu M.,

40

Non tutti i compiti possono essere svolti in uno sprint (artificiale) di 2 settimane, quindi è richiesto il buon senso. Se non può più essere scomposto e deve essere fatto, basta andare avanti e farlo. Il processo non è più importante del risultato finale e dovrebbe essere visto come una linea guida piuttosto che una legge da non infrangere.


3
La tua risposta è un'ottima informazione sull'argomento. Sono qui per "salire e farlo" come dici tu. Ho posto la domanda nella speranza di ottenere alcune informazioni in modo da poter elaborare un processo da eseguire parallelamente a quello esistente o in qualche modo modificare il processo corrente per risolvere la mia situazione attuale. Ho bisogno di qualcosa da dire agli sviluppatori in modo che abbiano delle linee guida all'interno delle quali lavorare, poiché ciò avverrà almeno altre 2 volte.
Charles Lambert,

+1 per "Il processo non è più importante del risultato finale e dovrebbe essere visto come una linea guida piuttosto che una legge da non infrangere". - La gente sembra davvero dimenticarlo.
Bjarke Freund-Hansen,

32

Fai uno sprint di 3, 4 o 5 settimane. Che importa? Ovviamente sei convinto che nulla può essere fatto in un lasso di tempo più breve, quindi smetti di combatterlo.

Non dirlo ai tuoi compagni alla Royal Society of Blind Agile Adherance.


sembra che per motivi organizzativi (hotfix mensili), gli sprint di 2 settimane siano piuttosto difficili da cambiare.
Steve Bennett,

10

Consiglio di iniziare con il libro Working Effectively with Legacy Code , di Michael Feathers. Copre una varietà di tecniche per ridurre la portata delle modifiche allo stile del refactoring.


Un buon libro di sicuro, ma non credo che copra il refactoring di divisione su più sprint.
Adam Lear

4
Darò un +1 perché è probabilmente il miglior libro con cui iniziare quando inizi a imparare, come dice il titolo, a lavorare efficacemente con il codice legacy. È rilevante per qualcuno che potrebbe porre questa domanda e non capire cosa è coinvolto nel rompere le cose in piccoli passi.
Charles Lambert,

@Anna - allora potresti voler (ri) leggere il capitolo 25, che parla delle tecniche per rompere il tipo di accoppiamenti che impediscono piccoli cambiamenti.
kdgregory,

@kdgregory Abbastanza giusto. :) Ti dispiace aggiungerlo alla tua risposta per renderlo più fantastico?
Adam Lear

7

Nel nostro negozio, quando abbiamo grandi attività di refactoring o riscrittura che non possono essere completate in una finestra di rilascio, lasciamo la funzionalità così com'è nel sistema. Ma iniziamo con le nuove funzioni di blocco lego refactored come il tempo lo consente. Alla fine, arriviamo a uno stato in cui abbiamo fatto abbastanza lego-blocchi, che uno sprint fornisce il tempo sufficiente per collegare i blocchi lego nell'applicazione e attivarlo per gli utenti.

Più concisamente, suddividiamo o rielaboriamo grandi funzioni usando nuovi nomi. Quindi, alla fine, usiamo il nostro lavoro rinominato e refactored invece del brutto vecchio codice.


Questa è una buona idea, ma richiederebbe un alto livello di comunicazione per attuare. Ad esempio, quando sto codificando, se identifico un metodo che non viene utilizzato da nessuna parte e non è pubblico, lo rimuoverò.
Charles Lambert,

5

Dedica uno sprint a capire come far funzionare correttamente il codice a metà refactoring. Questo può assumere la forma di metodi e classi deprecati, involucri, adattatori e simili. Il refactoring potrebbe rendere il codice più sporco per un breve periodo al fine di essere più pulito a lungo termine; va bene. In questo momento stai dicendo che non può essere fatto. Non credo sia giusto: pensa a come sarebbe il tuo processo se potesse essere fatto, pensa a quali passi puoi fare per renderlo tale. Quindi tuffati.


Abbiamo già fatto tutto questo. Questo era il motivo per cui espressi chiaramente che non poteva essere scomposto.
Charles Lambert,

Veramente? Hai trascorso un intero sprint semplicemente pianificando come eseguire il refactoring senza rompere il sistema e non hai trovato nulla? Trovo difficile credere che uno sprint di pianificazione dedicato non abbia prodotto nulla; forse devi rivolgerti a un consulente (e no, io non sono uno, non sto cercando di ottenere un concerto).
Carl Manaster,

1
Non ho detto niente del genere. Stavo dicendo che abbiamo attraversato un processo simile a quello che hai descritto e siamo usciti dall'altra parte con del codice che non può essere refactored in un singolo sprint.
Charles Lambert,

Ho detto: "Dedica uno sprint a capire come far funzionare correttamente il codice a metà del refattore". Hai detto: "Abbiamo già fatto tutto questo". Stai dicendo ora il contrario? Mi dispiace se questo sembra controverso, ma non capisco.
Carl Manaster,

5

+1 sulla risposta di Corbin March, è esattamente quello che stavo pensando. Sembra che la tua base di codice sia un po 'brutta e ci vorrà più di un singolo ciclo di sprint per ripulirlo.
Quindi, proprio come ha detto Corbin,

  1. diramarlo in un "progetto di refactoring"
  2. prova il tuo cambio di filiale
  3. promuovere nel proprio ambiente di test per i test di qualità
  4. ricollocarlo in modo incrementale nel bagagliaio fino al completamento del refactoring.

Sono sicuro che non avresti problemi a vendere questo al tuo manager di sviluppo, se i tuoi PM non riescono a vederlo, spiega loro che Roma non è stata costruita in un giorno e ripulisce tutta la spazzatura gettata in quella di Roma le strade non si faranno neanche in un giorno. Il refactoring richiederà un po 'di tempo, ma alla fine ne varrà la pena in termini di manutenzione più semplice, rilasci di miglioramento più rapidi, meno biglietti di produzione e uno SLA più soddisfatto.


1
Ho tutte le munizioni di cui ho bisogno per parlarne tutti. Ho solo bisogno di un piano ufficiale per eseguirlo, quando lo presento. Dalle risposte qui, non ho dubbi sul fatto che troverò una soluzione ripetibile.
Charles Lambert,

4

Anche se la riprogettazione che vuoi veramente fare è un grande compito, sarebbe possibile riformattare pezzi più piccoli per spezzare / disaccoppiare le dipendenze individuali? Sai - in caso di dubbio, aggiungi il riferimento indiretto. Ognuno di questi disaccoppiamenti dovrebbe essere un compito più piccolo di quello mammut che non puoi completare.

Una volta rimosse le dipendenze, dovresti essere in grado di suddividere le attività di refactoring rimanenti per essere ottenibili negli sprint.


3

Nel progetto per il quale sto lavorando al momento, stiamo usando sprint di 4 settimane. E a volte non siamo in grado di finire una user story e la riavviamo solo durante lo sprint seguente.

Tuttavia, IMHO dovrebbe essere possibile suddividere un refactoring in storie più piccole che rientrano in uno sprint di 4 settimane. Se non riesci a portare il codice in uno stato coerente entro 4 settimane, ho la sensazione che tu stia riscrivendo la tua applicazione piuttosto che riformattarla.


uno sprint di 4 settimane dovrebbe coprirlo. Tuttavia, non possiamo interrompere gli sprint di 2 settimane attuali a causa di altre correzioni di bug, ecc. Quindi questo dovrebbe estendersi attraverso più di uno sprint. Quindi il nocciolo del mio problema.
Charles Lambert,

Come ho detto, stiamo usando gli sprint di 4 settimane e, se una storia non è finita in 4 settimane, la programmiamo solo per lo sprint successivo. Puoi almeno avere il sistema in uno stato coerente al termine di uno sprint di 2 settimane (e quindi continuare durante lo sprint successivo)?
Giorgio,

Non è uno stato coerente verificabile .
Charles Lambert,

Devo aggiungere la mia ondata allo sforzo che gli altri hanno fatto per sperare che troverai un'altra parola da usare piuttosto che "refactoring". Il refactoring è ben definito e la sua portata è molto più immediata e di breve durata rispetto alla riprogettazione e alla riprogrammazione massiccia e dispendiosa in termini di tempo che è necessario eseguire.
John Tobler,

2

Raccomando che quando alcune attività richiederanno più tempo del ciclo di sprint di 2 settimane, l'attività verrà programmata per un'altra volta. Il tuo team ha identificato la necessità di refactoring e questo è importante. A volte, non c'è altra opzione ... e, sì, che fa schifo.

Quando arriverà il momento di iniziare il refactoring, dovrai semplicemente sospendere gli sprint normali. Non hai scelta. Utilizza il controllo intelligente della versione: diramazione, refactor, test, unione. C'è sempre un momento nel quale il refactoring di alcuni grandi progetti ha la priorità sulle funzionalità. Se possibile, tenterei anche di separare le preoccupazioni per una migliore flessibilità.


Non possiamo rimandare per sempre, e la tua risposta non riguarda come eseguire il refactoring.
Charles Lambert,

@Charles: "previsto per un'altra volta". ;) Non ho detto di annullare il progetto.
Estratto del

2

Avendo recentemente riscontrato lo stesso problema con una parte della nostra base di codice (che è anche un po 'più grande), spero di poter condividere alcune informazioni con te. Nella mia situazione, il codebase era stato sviluppato da un altro team, quindi nessuno degli sviluppatori originali era coinvolto in questo refactoring. La mia esperienza con il codebase è stata di circa 1 anno, e un altro sviluppatore l'ha incaricato 2 anni.

Consentitemi due piccole note riguardanti le altre risposte qui:

  • Le ramificazioni ti aiuteranno a creare un parco giochi per te, ma non unire mai le modifiche al trunk in un grande changeset. Ti metterai seriamente nei guai con il resto della squadra.
  • Devi farlo in modo incrementale e puoi farlo. Niente scuse. Leggi Lavorare in modo efficiente con la copertina del codice legacy . Leggilo di nuovo
  • Pensare di poterlo fare un grande passo è un errore. Anche se sembra più lavoro, farlo in modo incrementale è molto più facile da gestire.

Andare apparentemente "fuori prenotazione" per due settimane o più non passerà inosservato. Devi assicurarti di essere supportato dalla gestione del progetto e, soprattutto, dal team. Se la squadra non è impegnata in questo refactoring (e questo significa, fallo ora, non in un lontano futuro), ti metterai nei guai.

Non farlo da solo, usa la programmazione in coppia. Questo non significa strettamente che devi sedere sempre davanti alla stessa tastiera, ma puoi gestire compiti piccoli e ristretti (ad esempio scrivere test che catturino il comportamento di questa classe) individualmente.

Effettua un refactoring antigraffio e trattalo come tale. (Una sorta di refactoring prototipo "usa e getta", il bit "usa e getta" è importante!) Onestamente, è improbabile che tu sappia tutte le implicazioni che avrà il tuo refactoring. Un refactoring antigraffio ti aiuterà in alcuni aspetti:

  • Scoprirai parti del sistema che non sapevi che esistessero.
  • Avrai una visione molto migliore di come i moduli si collegano
  • Scoprirai un nuovo modo di raggruppare il tuo sistema in moduli, probabilmente molto diverso dalla tua attuale comprensione. Discuti approfondimenti con il tuo partner. Prova a distillare la tua nuova vista. Scrivi un breve white paper sull'architettura (o disegna un diagramma) che indichi dove sono attualmente le cose e dove dovrebbero logicamente appartenere.

Quando avrai finito il refactoring, spero che scoprirai che non puoi semplicemente andare e cambiare tutto dappertutto. Ti sentirai male, è solo un gran casino e non puoi semplicemente premere un interruttore e farlo funzionare. Questo è quello che mi è successo, potrebbe essere diverso nella tua situazione.

Tuttavia, io e il mio partner avevamo una comprensione molto migliore del nostro sistema. Ora siamo stati in grado di identificare rifatturazioni / riprogettazioni individuali, più piccole (anche se ancora di grandi dimensioni). Abbiamo catturato la nostra visione del sistema in un diagramma e condiviso con il team, insieme agli elementi arretrati che abbiamo ideato per implementare quella visione. Grazie al consenso comune, abbiamo deciso quali elementi avremmo implementato nel corso della prossima iterazione.

Un'ultima cosa che ci ha aiutato è stata l'uso di una grande lavagna. Ci sono troppe cose da tenere in testa. È assolutamente importante tenere appunti. Scrivi a te stesso una nota informativa alla fine della giornata, catturando ciò che hai fatto oggi e vuoi fare domani. Aiuta a rilassare grandi momenti e hai bisogno di un momento di relax se vuoi tenere il passo con il compito. In bocca al lupo!


1

Avviare una finestra di manutenzione durante la quale non viene eseguito alcun ulteriore sviluppo. Esegui la riprogettazione, quindi riprendi gli sprint di sviluppo.


0

Abbiamo due tipi di lavori a portata di mano:

  1. Man-hour funziona
  2. Genius funziona

Il refactoring di solito consiste nel primo tipo di lavoro, poiché molti metodi sono già noti a sviluppatori come DRY , SRP , OCP , DI , ecc. Quindi quando un progetto impiega due mesi per essere refactored, ci vogliono semplicemente due mesi , c'è nessun modo per aggirarlo. Pertanto, il mio suggerimento sarebbe di non riformattare il progetto originale e lasciarlo funzionare sulla sua situazione attuale. Non ricevere più nuove richieste e requisiti dalle parti interessate e dal proprietario del prodotto . Quindi lascia che il team lavori sul progetto fino a quando non viene refactored e pronto per partire.


0

Un suggerimento che può essere d'aiuto: se disponi di un codice non testato in modo tale da non avere tempo sufficiente per eseguire il refactoring e ripetere il test entro lo sprint di due settimane, considera innanzitutto di apportare altre piccole modifiche non correlate al codice in modo da poter concentrare durante la scrittura di test per il primo o due sprint. Forse è possibile identificare diversi client non testati del codice che si desidera refactoring; scegli un cliente e apporta altre modifiche di qualche utilità all'azienda che ti costringeranno a scrivere test per quel cliente. Dopo aver acquisito maggiore familiarità con il codice, lavorando con esso e dopo aver eseguito più test e probabilmente aver eseguito alcuni piccoli refactoring contribuenti, sarà in una posizione molto migliore per eseguire il refactoring e il (ora più semplice ) testando entrambi in una iterazione.

Un altro approccio è quello di creare una copia del codice offensivo, riformattarlo e quindi spostare i client uno alla volta nel nuovo codice. Questo lavoro può essere suddiviso in più iterazioni.

E non arrenderti: non accettare semplicemente che un grande refactoring non può essere suddiviso in passaggi più piccoli. L'approccio più semplice / veloce / migliore potrebbe richiedere più tempo di un'iterazione. Ma ciò non significa che non c'è modo di eseguire blocchi di dimensioni iterative.

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.