Come posso refactificare una base di codice mentre altri si impegnano rapidamente in essa?


18

Sono su un progetto privato che alla fine diventerà open source. Abbiamo alcuni membri del team, abbastanza talentuosi con le tecnologie per creare app, ma non sviluppatori dedicati che possono scrivere codice pulito / bello e, soprattutto, a lungo termine.

Ho deciso di riformattare la base di codice, ma è un po 'ingombrante dato che qualcuno nella squadra in un altro paese con cui non sono in contatto regolare potrebbe aggiornare questa cosa totalmente separata.

So che una soluzione è comunicare rapidamente o adottare migliori pratiche di PM, ma non siamo ancora così grandi. Voglio solo ripulire il codice e unirmi bene in ciò che ha aggiornato. L'uso di un ramo sarebbe un piano adatto? Un'unione best-effort? Qualcos'altro?

Risposte:


35

Una cosa che le persone spesso non riescono a considerare è che un'architettura pulita non solo accelera la manutenzione a lungo termine, ma accelera anche lo sviluppo in questo momento . Non cercare di isolare le modifiche dai tuoi colleghi fino a quando non sono "completate". Le tue modifiche li aiuteranno a essere più produttivi e meno inclini a bug.

L'errore più frequente che le persone commettono quando intraprendono un grande refattore è quello di non fondersi abbastanza spesso, invece di provare a farlo in un "big bang". Il modo giusto per farlo è quello di creare il più piccolo refattore possibile, testarlo, quindi unirlo nel ramo del tuo collega e insegnargli il cambiamento in modo che possa incorporarlo in futuro. Idealmente stai facendo una fusione al giorno, o almeno una alla settimana.


17
Sì sì sì. Resisti alla tentazione di fare un tour-de-force da solo di un mese solo per scoprire che la base di codice che dovresti refactoring è completamente cambiata e devi ricominciare tutto da capo. Meglio farlo un passo alla volta.
martedì

Completamente giusto! I grandi refactoring non vanno da nessuna parte (vedi Netscape 6 , o Project Pyramid )
Andomar

8

Non sei mai "non abbastanza grande per comunicare". Se le dita riescono a scrivere, anche le tue labbra possono parlare. Alla fine della giornata il miglioramento della tecnologia è dell'85% di comunicazione e del 15% tecnico. Solo perché preferiresti sederti lì a programmare piuttosto che avere conversazioni difficili con qualcuno ... non significa che sia una buona idea. La comunicazione è in realtà il duro pezzo di ciò che stai cercando di fare, ma non solo evitarlo.


Non è proprio la difficoltà di comunicare, è che non voglio che l'attuale sviluppatore rallenti. In realtà, non sono nemmeno sicuro che abbia bisogno di imparare nel modo giusto fintanto che può essere refactored. Prima non è un programmatore, è uno scienziato in un altro campo.
Incognito

+1. Non puoi condividere una base di codice con qualcuno senza comunicare
MarkJ,

4

Sì, un ramo è una buona soluzione per questo.

Ti suggerirei di iniziare a lavorare su questo in un ramo e assicurarti che si applichi in modo pulito al di sopra della tua corrente HEADnel frattempo (ad esempio, esegui rinnovi e fusioni di test a intervalli regolari per assicurarti di poter applicare facilmente le modifiche e i test ancora superano - - cercagit rerere anche aiuto da gitquesto). Quindi, una volta terminato il rebase e unisci le modifiche al tuo HEAD.

Prima inizi a lavorarci su, meglio è dal momento che cambiare architettura diventa sempre più lavoro, più il codice diventa freddo. Inoltre, potrebbero esserci molte istanze di codice codificato a mano sparse in tutta la base di codice in cui, ad esempio, la funzione di aiuto nuovo e shiner potrebbe aver semplificato le cose.


1
-1: No. Vedi la risposta di @Karl Bielefeldt.
Jim G.

Sì? Non sono in disaccordo con Karl, è per questo che ho sottolineato la necessità di iniziare velocemente.
Benjamin Bannier,

E sto dicendo "Non diramare e poi ricollegare". Nel migliore dei casi, è uno sforzo sprecato. Nel peggiore dei casi, farai un casino enorme.
Jim G.

3

Hai considerato l'opzione "Non farlo ancora"?

Mentre fare questo lavoro in un ramo separato è probabilmente l'approccio migliore, ti stai preparando per un'enorme fusione dolorosa lungo la linea.

Gli altri ragazzi stanno presumibilmente aggiungendo molte nuove funzionalità, cambiando le funzionalità esistenti e forse rimuovendo alcune funzionalità.

Una volta che lo sviluppo principale ha funzionato ha rallentato un po 'ad un certo punto in futuro, allora potresti essere in una posizione molto più facile da refactoring.


+1. Se il tuo codebase ha un flusso enorme, probabilmente non è il momento migliore per provare una grande riscrittura. Scegli un momento nel tuo ciclo di sviluppo quando le cose sono più tranquille.
anon

2

tl; dr - Sembra che sia ora di passare ai campionati più importanti. Mettere il rossetto su un maiale non lo rende più carino, a meno che non ti piaccia quel genere di cose ...

Il problema delle persone

Il primo problema è la sincronizzazione del commit. SE hai più persone che lavorano allo stesso codice contemporaneamente, devi solo una regola per prevenire problemi:

Rule 1: Always pull before you merge/rebase

Quando si tratta di DVCS, è difficile apportare modifiche a un ramo remoto (ovvero il repository principale) e molto facile apportare modifiche al locale. Ogni persona è responsabile di far sì che le proprie aggiunte di codice si adattino al tutto senza problemi. A meno che 2 persone non si impegnino nello stesso momento, non dovresti provare. L'accesso commit all'origine / master remoto dovrebbe essere limitato a pochi sviluppatori e dovrebbero estrarre le modifiche dagli altri sviluppatori tramite filiali di tracciamento remote.

Il problema del codice

Come fai a sapere che le modifiche apportate non infrangono il codice?

Risposta semplice ... Scrivi dei test per provare che non lo fanno. Se si ignora la scuola di pensiero TDD (Test Driven Design), l'intero punto dei test è aggiungere un livello di verifica che consenta di modificare il codice senza romperlo.

Rule 2: Don't make assumptions, write proofs (ie tests).

Inoltre, è necessario eseguire l'intera gamma di test prima di passare al master origine / remoto.

Mantieni i tuoi impegni il più piccolo e conciso possibile. In questo modo, se è necessario annullare una modifica che ha interrotto qualcosa in seguito, si eviterà di dover implementare nuovamente le parti che non hanno violato il codice.

Per prima cosa potresti aver bisogno di qualche ristrutturazione organizzativa

Se le soluzioni di cui sopra non possono essere facilmente applicate, probabilmente ci sono alcuni problemi con la struttura di sviluppo che devono essere affrontati per primi.

Il proprietario del progetto dovrebbe essere il gatekeeper. Se ci sono problemi di sincronizzazione del commit, probabilmente ci sono troppe persone con accesso commit. Anche su grandi progetti come il kernel Linux, solo una manciata di sviluppatori ha eseguito l'accesso al repository principale di origine / remoto. Esistono in realtà più livelli di repository per gestire i commit. Invece di un modello di commit a livello singolo in cui tutti stanno spingendo le loro modifiche all'origine, il modello gerarchico ha gatekeeper che effettuano modifiche e ne verificano la qualità prima dell'inclusione nel progetto. Il modello gerarchico di commit può ridimensionare molto più grande ed efficace del modello a singolo strato senza sacrificare la qualità.

Per gli sviluppatori che non vengono commettono l'accesso, si dovrebbe imparare a creare il proprio remoti rami di tracciamento (git e Gitorious sono buone per questo) in modo gli sviluppatori che fanno abbia l'accesso commit può facilmente tirare / integrate rami l'origine. Se le modifiche sono piccole, le patch funzioneranno altrettanto bene.

La capacità di estrarre le modifiche prima di eseguire l'unione / rebase presuppone che non si stia sviluppando nel ramo master locale. Il modo più semplice per gestirlo è effettuare un pull iniziale prima di iniziare a programmare, quindi fare tutto il lavoro su quel ramo. Il modo più difficile è ramificarlo appena prima di unire e ripristinare il master.

Definisci lo stile di codifica per il progetto in generale e fai in modo che gli sviluppatori lo seguano. Gli sviluppatori che contribuiscono dovrebbero scrivere un codice conforme agli standard / norme del progetto per ridurre al minimo la pulizia. Lo stile di programmazione può essere una grande barriera dell'ego in un progetto aperto. Se non viene impostato nessuno standard, ognuno codificherà nel proprio stile preferito e la base di codice diventerà molto brutta molto velocemente.

Il mito di "The Mythical Man Month"

Che ci crediate o no, i progetti open source più grandi / di maggior successo non sono gestiti come una democrazia. Sono gestiti come una gerarchia. Dichiarare che un progetto non può crescere efficacemente oltre gli 8-10 sviluppatori è ingenuo. Se ciò fosse vero, non esisterebbero mega-progetti come il kernel Linux. Il problema più profondo è che dare a tutti l'accesso al commit rende la comunicazione efficace troppo difficile da gestire.

Il problema del mese dell'uomo mitico può effettivamente essere superato. Hai solo bisogno di gestire il tuo progetto come i militari. Ci sono molti livelli all'interno della gerarchia perché è risaputo che le singole persone sono davvero efficaci solo nel gestire le comunicazioni con una manciata di persone. Finché nessun singolo individuo è responsabile della gestione del lavoro di più di 5-7 persone, il sistema può ridimensionarsi indefinitamente.

Potrebbe limitare gli sviluppatori più esperti a fare maggiore integrazione e progettazione / pianificazione di livello superiore, ma non è una cosa negativa. Parte del ridimensionamento consiste nel decidere se il progetto necessita di un piano a lungo termine. Le persone ai massimi livelli che hanno i maggiori investimenti (il tempo è anche una risorsa) per i progetti futuri dovrebbero essere incaricate di prendere le grandi decisioni.

È bello sapere di un progetto open source che sta attraversando dolori crescenti. Complimenti e buona fortuna.


-1

codice mantenibile pulito / bello e soprattutto a lungo termine.

Nella mia esperienza, pulito / bello è nemico del mantenibile. Bellissimo codice spesso:

  • Ha uno strato sul framework che introduce un livello più alto di astrazione
  • Ottimizza il riutilizzo del codice, causando molte dipendenze
  • Cerca di risolvere il problema generico anziché quello specifico

D'altra parte, codice gestibile:

  • È scritto direttamente sul framework, quindi tutti gli sviluppatori possono leggerlo
  • Ottimizza per un basso numero di dipendenze, quindi un cambiamento in un'area non influisce su un'altra
  • Non cerca di risolvere più problemi di quanti ne debba fare

La tua bella descrizione del codice può andare di pari passo con il codice gestibile anche perché quando si introduce un livello più alto di astrazione e si ottimizza il codice per il riutilizzo, è comunque più facile da mantenere.
Karthik Sreenivasan,

Solo che l'astrazione non resisterà alla prova del tempo. E qualsiasi problema con l'astrazione solleva una correzione locale in una correzione che potenzialmente ha un impatto a livello di applicazione.
Andomar,
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.