Quanto dovrebbe essere pulito il nuovo codice? [duplicare]

32

Sono il lead designer del nostro team, il che significa che sono responsabile della qualità del codice; funzionalità, manutenibilità e leggibilità.

Quanto è pulito dovrei richiedere il codice dei membri del mio team se non abbiamo poco tempo?

A mio avviso, dovremmo pulire il vecchio codice che modifichiamo; aggiungere una linea a un metodo significa ripulire quel metodo.

Ma per quanto riguarda il nuovo codice?

Potremmo renderlo perfettamente pulito, così che se un altro programmatore arriva domani e fa una piccola modifica, non deve affatto ripulirlo. Ma questo significa che se nessuno legge mai più quel pezzo di codice, abbiamo perso tempo a renderlo perfettamente pulito.

Dovremmo mirare a "quasi pulito" e poi ripulirlo ulteriormente nelle visite future? Ma ciò significherebbe non ottenere il pieno valore per la comprensione che abbiamo avuto quando l'abbiamo scritto in primo luogo.

In questo momento, vado per "perfettamente pulito"; in parte come tutorial per i miei colleghi che non sono così esigenti come me.

    
posta Roger C S Wernersson 23.10.2011 - 22:02
fonte

9 risposte

35

La mia esperienza:

  1. Un pezzo di codice più lungo di 20 righe, scritto come proof-of-concept, non verrà riscritto quando il concetto così dimostrato è necessario, ma piuttosto piegato a in forma le esigenze del codice di produzione .

  2. Di solito, questo è accompagnato dalla promessa di riscriverlo più tardi, quando c'è tempo per fare tutto correttamente. Tuttavia, questa volta non viene mai, quindi questo codice di test sarà bloccato nel codice di produzione per sempre .

  3. Qualsiasi progetto software più grande di, ad esempio, 2 mesi uomo sta sulle spalle di almeno un pezzo di tale codice di prova-di-idea toying-with-the-idea, grandi progetti sono costruiti su molti di essi . E nessuno sostituirà questi pezzi di codice che di solito sono caratteristiche vitali sottostanti dell'applicazione, minacciando di abbattere tutto su un singolo errore.

  4. Troppi grandi progetti prima o poi inciampare su tale codice .

La mia soluzione:

Qualcosa di più di 20 righe di codice deve essere solido e a prova di proiettile. Progettare correttamente l'intera cosa, non usare gli hack per risparmiare tempo, fare sforzi nella scelta di buoni identificatori, refattore non appena ne vedi la necessità, ... L'enchilada intera.

Anche se l'80% di questi frammenti è davvero gettato via, il resto finirà nel cuore di un codice che mantiene la società a galla per un decennio lungo la strada. Quella prospettiva scusa qualsiasi sforzo riversato in un piccolo programma apparentemente unico.

    
risposta data 23.10.2011 - 23:05
fonte
27

Nella mia esperienza, rendere il nuovo codice pulito non è poi così difficile. Di solito hai in mente un concetto unico e chiaro su cosa dovrebbe fare il codice, come implementarlo ecc. Quindi è abbastanza facile organizzare il codice per riflettere chiaramente questa cosa (almeno secondo la propria comprensione corrente - ritornare per lo stesso pezzo di codice 6 mesi dopo può rivelare alcune sorprese; -).

Il problema si presenta quando il codice esistente deve essere modificato / esteso. Poi inizia a diventare più complesso, la chiara visione architettonica / di progettazione originale si sta offuscando, quindi dobbiamo dedicare uno sforzo cosciente al refactoring e tenere sotto controllo l'entropia del codice.

Creare una parte di codice così pulita come sarebbe potrebbe rendere più facile estensioni e manutenzione future. Se ci sono modifiche future, questo è. Altrimenti, come si nota, lo sforzo è "sprecato" - almeno nel senso diretto. Tuttavia, ci sono ulteriori cose da considerare:

  • Il fatto che una parte di codice non sia mai stata modificata finora non significa che non sarà mai
  • Qualsiasi parte di codice viene in genere letta molte più volte di quella modificata
  • È meglio abituarsi a scrivere codice pulito come un'abitudine, piuttosto che cercare di decidere ogni volta se questa particolare parte di codice è importante o abbastanza critica da essere resa più pulita. Pensare a questo potrebbe richiedere più tempo del miglioramento effettivo del codice e alcuni sviluppatori potrebbero facilmente iniziare a utilizzare questa regola per giustificare la loro pigrizia o resistenza ai nuovi modi
  • Più pratichi un'abilità, meglio la prendi *; e scrivere codice pulito è abbastanza importante da essere praticato costantemente.

Tutto sommato, questo tipo di argomenti porta al contrario di YAGNI : in questo caso stai andando Bisogno di essa. Se hai tempo, scrivi il codice pulito che puoi. (Ma non è più pulito - a un certo punto la regola dei rendimenti decrescenti prende il via, quindi dovremmo fermarci e trovare qualcosa di meglio da fare. Per evitare di lucidare incessantemente le stesse 3 righe di codice, dobbiamo concentrarci su cambiamenti significativi che rappresentano un reale miglioramento leggibilità / manutenibilità).

* Non ho sentito nessun adulto in buona salute lamentarsi di quanto sia difficile camminare, ma assistere un bambino o una persona ferita che sta cercando di (ri) apprenderlo ti fa capire quanto sia complesso un risultato. Tuttavia, la maggior parte di noi lo fa tutto il tempo senza nemmeno pensarci coscientemente.

    
risposta data 23.10.2011 - 22:28
fonte
12

Dipende. Vorrei creare due casi, uno per il nuovo codice e uno per il codice esistente.

Per il nuovo codice, consiglierei di utilizzare lo sviluppo basato sui test (TDD) oltre al refactoring spietato come prassi standard. Rendilo il più semplice possibile effettuando il refactoring e fermalo solo quando non riesci più a pensare a nessun miglioramento. Mentre questo può sembrare un grande sforzo, al momento si scopre che ripaga molte volte. In altre parole, sì, rendilo "perfettamente pulito".

Per il codice esistente, tuttavia, sarei molto più attento. Dipende dalla qualità e dalla copertura della tua suite di test. In genere il codice esistente è il codice che è stato in uso per un bel po 'di tempo. Questo significa anche che probabilmente la maggior parte degli errori sono stati corretti. Quando inizi a cambiare questo codice, assicurati di non rompere nulla che funzioni. La mia raccomandazione sarebbe di scrivere prima i test. Un mucchio di questi per assicurarti di capire chiaramente cosa fa il codice esistente, ma anche per assicurarti che quando inizi a ripulirlo non rompi accidentalmente nulla.

La scelta dell'approccio dipende anche dagli strumenti disponibili. Il refactoring e l'unit test support possono essere abbastanza diversi per le diverse lingue. Assicurati di ottenere i migliori strumenti possibili. Indipendentemente dal prezzo, ne vale la pena.

Ci sono altri aspetti su come lavorare con il codice legacy. Vorrei raccomandare di leggere il libro di Mike Feather "Lavorare efficacemente con il codice legacy" . Buona fortuna!

    
risposta data 23.10.2011 - 22:17
fonte
10

Negli ultimi anni ho scoperto una regola del ferro:

Il codice vive sempre più a lungo del previsto .

Quella sparatoria one-shot che hai buttato insieme in mezz'ora affinché il marketing possa modificare del testo su una pagina non critica progettata per due settimane di utilizzo della produzione sarà probabilmente ancora in uso quando lascerai la compagnia due anni dopo . Quel piccolo script di distribuzione che utilizzi per ora verrà utilizzato fino alla morte dell'intero progetto. Quel piccolo sostituto che useremo-questo-fino-alla-vera-cosa-è-finito per la componente ORM di terze parti commerciale e ora defunta potrebbe diventare la vera cosa stessa.

Inoltre, la pulizia del codice non richiede più tempo. Lo fa se scrivi un camion di codice quick-and-dirty e poi lo pulisci, ma se inizi a pulire e tienilo pulito lungo la strada, è spesso anche più veloce.

Un musicista davvero bravo mi ha detto una volta: "Suona sempre al meglio che puoi, anche quando fai dei riscaldamenti nella tua camera d'albergo, dagli tutto quello che hai, non sai mai chi c'è nella stanza la prossima porta ad ascoltare.

    
risposta data 24.10.2011 - 08:18
fonte
4

Per ogni programmatore del team, la risposta dovrebbe essere sempre "un po 'più pulita del codice che ho scritto la settimana scorsa".

Troppo spesso, avere una specifica e severa regola negli standard di codifica di un'organizzazione porta a una disconnessione tra ciò che è ufficialmente previsto e ciò che realmente accade. La maggior parte dei programmatori di abilità media non può o non vuole cambiare improvvisamente le proprie abitudini durante la notte, e anche se regolarmente raggiungono gli standard, avranno i giorni liberi. Nel mondo reale, è più pratico concentrarsi sul miglioramento rispetto alla perfezione.

    
risposta data 23.10.2011 - 23:15
fonte
1

Sempre disponibile per quanto possibile pulito al momento della stesura di . Risparmiare tempo scrivendo il codice sciatto è una falsa economia, un prezzo viene pagato per ogni scorciatoia ogni volta che risolvi un bug o modifichi il tuo codice.

Il rifrattore del vecchio codice è meno chiaro e dipende dal giudizio del programmatore in quel momento. A volte è "giusto" scrivere in uno stile meno pulito che sia coerente con un altro codice. Refractare il codice esistente è sia difficile che richiede tempo. A volte non è conveniente riscrivere grossi pezzi di codice funzionante per una modifica.

    
risposta data 23.10.2011 - 22:41
fonte
1

La chiave è ripulire il codice che è più probabile che funzioni di nuovo.

Lavorare con codice ben fattorizzato è più divertente e più probabile che produca il risultato desiderato . Questi sono entrambi importanti.

Tuttavia, il refactoring richiede tempo e tutte le modifiche portano il rischio di nuovi bug. Il codice di refactoring a cui non hai bisogno di lavorare è una cattiva idea.

Come sapere in quale codice devi lavorare? Le modifiche tendono ad accadere insieme , nelle aree ad alto tasso di abbandono, mentre altre aree vengono lasciate inattive per un lungo periodo di tempo. Ci sono molte ragioni per questo fenomeno; uno è che le modifiche che apporti al momento sono probabilmente sbagliate, ma non puoi saperlo finché non sono terminate.

Quindi, utilizzo la seguente sequenza quando lavoro su una funzionalità o correzione di un bug:

  1. Immagina come sarebbe il codice se fosse ideale per la modifica che voglio apportare, in modo che la modifica sia una semplice riga modifica che era ovviamente corretta?

  2. Immagina un percorso dei refactoring per ottenere le cose fino a quel punto.

  3. Esegui un refactoring alla volta , esegui il test mentre procedo e esegui il check-in di ogni refactoring separatamente, con una descrizione di modifica speciale che inizia con "REFACTORING:". Questo aiuta a rendere ovvio che se stai cercando un cambiamento deliberato del comportamento, non devi guardare a questo. Inoltre, poiché la maggior parte dei refactoring è ben definita con nomi noti, è facile capire queste modifiche in seguito.

  4. Apporta la modifica di una riga per ottenere la modifica della funzionalità desiderata.

Questo approccio funziona altrettanto bene per le modifiche alle funzionalità esistenti così come per l'aggiunta di nuove funzionalità, dato che tutto è codice esistente dopo il giorno 1. Tuttavia, se ti stai indirizzando verso una nuova area di funzionalità per il tuo programma, può avere senso lanciare un'implementazione rapida e sporca insieme per ottenere un feedback reale sui tuoi piani.

Ci sono molti :

  • Se una scadenza si avvicina, i rischi dei refactoring possono superare i benefici. È richiesto il giudizio.

  • A volte il codice richiederebbe un ampio refactoring per fare in modo che questo funzioni, ma sarebbe possibile implementare la funzione o la correzione dei bug desiderati abbastanza facilmente. In questo caso, potrei fare i più chiari, chiari refactoring ma non l'ideale descritto sopra.

  • Se non ho test automatici di alta qualità , i rischi del refactoring sono più preoccupanti. Potrei rifattorizzare di meno, a seconda delle circostanze. Tuttavia, il codice scarsamente fattorizzato è anche difficile da testare, quindi è facile finire in un pantano se non stai attento.

Nota che evito il refactoring nei confronti della struttura che ritengo possa essere utile per alcune modifiche future che non posso essere sicuro di aver bisogno. Refactor per il problema a portata di mano. Tuttavia, se questa non è la prima volta che ho bisogno di fare questo tipo di cambiamento, potrei ampliare l'ambito del refactoring in previsione di futuri cambiamenti simili. È necessaria la sentenza, ancora.

    
risposta data 24.10.2011 - 06:07
fonte
1

Da Rifattorizzazione: migliorare la progettazione del codice esistente , p58;

  1. The first time you do something, you just do it.
  2. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway.
  3. The third time you do something similar, you refactor.
    
risposta data 19.02.2012 - 03:38
fonte
0

Ho sempre avuto il desiderio di non ripetermi nel codice: lo considero il singolo disco più importante in un buon codice, quasi tutto il resto deriva da questo.

Così facendo ho scoperto che il codice di refactoring per eliminare la ridondanza è una delle pratiche più educative. Nel corso del tempo ho imparato a riconoscere più cose come ridondanti e più trucchi e trucchi da utilizzare per rifattorizzarli.

Inoltre, i refactoring combinati al codice si impilano come se non credessi. Si inizia dall'interno e si rifatta una manciata di affermazioni simili per utilizzare una struttura dati, che consente di identificare le somiglianze con altri pezzi di codice e rotola in salita con velocità sorprendente, riducendo il codice con il secchio lungo la strada.

Quindi perché non dovresti farlo ovunque tu abbia la possibilità, anche se non hai avuto molto tempo extra?

La maggior parte dei "Pulisci" extra nel tuo codice come la formattazione e i commenti provengono anche da questo processo - chi vuole documentare 5 pagine di codice ripetuto? Mentre li si isolano in una singola funzione, ora vale la pena documentarli!

    
risposta data 24.10.2011 - 04:06
fonte

Leggi altre domande sui tag