Qualcuno potrebbe spiegare i vantaggi dell'eliminazione (o della conservazione) del codice inutilizzato?


102

Ho sentito molte volte che il codice inutilizzato deve essere eliminato dal progetto. Tuttavia non è chiaro per me "perché?".

I miei punti per non eliminare che sono:

  • Il codice è già scritto e gli sforzi sono spesi
  • Il codice può essere testato su un ambiente sintetico e reale
  • Se ben organizzato (raggruppato, pacchetto separato, vagamente accoppiato ecc.) Non ti disturba sull'analisi complessiva del codice o sul refactoring
  • Il codice può essere utilizzato in futuro
  • Una volta cancellato, l'autore potrebbe sentirsi a disagio

Qualcuno potrebbe spiegare i vantaggi dell'eliminazione (o della conservazione) del codice inutilizzato?


16
Anche il codice commentato non dovrebbe appartenere a una base di codice.
leppie

27
Perché abbiamo il controllo della versione. Se dovessimo mai fare riferimento a vecchie versioni del codice, possiamo semplicemente rivedere la cronologia.
armandino

1
A proposito, fare riferimento al controllo della versione può essere difficile, quando il progetto è grande e alcuni file hanno> 200 revisioni
Alex Turbin

22
@AlexStamper, se i tuoi strumenti non ti consentono di esaminare facilmente le revisioni passate del tuo codice, la soluzione sarebbe quella di ottenere strumenti migliori, non di aggiungere rumore al tuo codice sorgente.
utnapistim

1
L'ingegneria del software ha una domanda molto simile .
davidvandebunte

Risposte:


180

Ecco alcuni motivi per cui il codice inutilizzato dovrebbe essere rimosso:

  • Chi lavora per la prima volta a un progetto, non deve solo comprendere il codice di lavoro, ma anche il materiale inutilizzato. Questo è tempo perso e crea confusione.

  • C'è il pericolo che prima o poi qualcuno apporti un cambiamento che inavvertitamente coinvolga il codice "dormiente" e possa introdurre bug. So che è successo su progetti su cui ho lavorato.

  • Il mantenimento di qualsiasi codice è un onere amministrativo. Preservando il vecchio codice ridondante tale onere è aumentato. Ad esempio, l'unione delle modifiche nel ramo principale diventa più difficile perché c'è più codice su cui lavorare e più possibilità di commettere un errore.

  • Quello che succede nel tempo è che sempre più codice vecchio inutilizzato viene aggiunto alla codebase. Ciò aumenta la confusione, i potenziali malintesi e le spese amministrative.

  • Le possibilità che il codice inutilizzato venga mai più utilizzato è molto improbabile. Con il tempo questa possibilità di riutilizzo diminuisce. Se il codice deve essere rimosso ed è considerato abbastanza importante, il codice può essere ramificato e documentato.

  • Tutti i sentimenti personali che un programmatore può avere sul codice su cui potrebbe aver lavorato duramente sono comprensibili. Ma parte dell'essere professionali richiede che quei pensieri debbano essere messi da parte per il bene migliore. Il tempo non è per nessuno e non c'è posto per preservare il codice storico in una base di codice funzionante.


26
Recentemente ho avuto la merda vivente spaventata a causa di guardare il codice inutilizzato (e non rendermi conto che era inutilizzato). Il codice inutilizzato dovrebbe essere eliminato dall'esistenza!
leppie

1
buoni punti, grazie. Anche i miei colleghi ne hanno dichiarati diversi
Alex Turbin

Ottima risposta. Vorrei fare riferimento ad argomenti come questi nella mia tesi di laurea, ma non riesco a trovare una fonte appropriata (libro, carta, ecc.). Hai qualche indizio?
Jonas Winkler

3
Sarei molto interessato alle tue ragioni per il voto negativo proprio ora.
suspectus

1
Un altro punto: se il vecchio codice è nuovamente necessario, la maggior parte dei progetti oggigiorno utilizza un SCM e il codice può essere recuperato di nuovo (a volte con qualche ricerca, vero, ma come chiaramente indicato nella risposta, la probabilità che il codice inutilizzato sia necessario di nuovo diminuisce con l'aumentare dell'età).
Chop

31

@suspectus ha svolto un ottimo lavoro nel presentare i motivi dell'eliminazione del codice; Vorrei affrontare i tuoi punti elenco individuali per mantenere il codice.

  • Il codice è già scritto e gli sforzi sono spesi

Ma se il codice già scritto non è in uso, questo è solo un costo senza valore (futuro). È uno sforzo investito invano e preservare il prodotto inutilizzato di quegli sforzi non convalida quegli sforzi. Manteniamo il codice perché è utile, ora, non come una sorta di memoriale degli sforzi degli autori.

  • Il codice può essere testato su un ambiente sintetico e reale

Mi dispiace, non so cosa intendi con questo.

  • Se ben organizzato (raggruppato, pacchetto separato, vagamente accoppiato ecc.) Non ti disturba sull'analisi complessiva del codice o sul refactoring

Se esiste nella base del codice, non importa quanto ben organizzato, contribuisce al carico di manutenzione e comprensione. È vero, può essere organizzato in modo da essere meno di un peso, ma se è andato, non è affatto un peso.

  • Il codice può essere utilizzato in futuro

Nella scuola Agile, diciamo YAGNI : Non ne avrai bisogno. Sì, potresti averne un uso in futuro, ma oggi non possiamo sapere abbastanza sulle esigenze di domani per poterlo prevedere con qualsiasi tipo di affidabilità. Pensare il contrario significa che l'arroganza tende all'arroganza. Quello che possiamo sapere di domani è: vogliamo che la nostra base di codice sia facile da modificare, e il codice inutilizzato sminuisce questa caratteristica.

  • Una volta cancellato, l'autore potrebbe sentirsi a disagio

L'autore deve superarlo. Abbiamo tutti scritto cose che si sono rivelate non utili - molto meglio essere in grado di puntare a un corpo di codice che è tutto in uso (perché il cruft inutilizzato è stato cancellato) che a un corpo di codice in cui puoi dire di alcuni metodi, "e quello è effettivamente in uso!"


17

Non è abbastanza difficile prendere del codice e capire l'intento, ma ora devi capire quali parti non sono in uso?


14

Il codice è già scritto e gli sforzi sono spesi

Inoltre non è necessario. Se non lo usi per niente, è (per definizione) inutile, a prescindere da quello che fa o da quanto impegno è stato speso per esso.

Il codice può essere testato su un ambiente sintetico e reale

Se è inutile, è ancora inutile anche se ci sono dei test. Se il codice è inutile, anche i test dovrebbero essere inutili (quindi mantenere il codice commentato lì, crea ambiguità - mantieni i test? Se avevi il codice client del codice commentato, commentate anche il codice client? )

Se ben organizzato (raggruppato, pacchetto separato, vagamente accoppiato ecc.) Non ti disturba sull'analisi complessiva del codice o sul refactoring

Non così. Tutti i tuoi strumenti (controllo del codice sorgente, analisi statica, estrattore di documentazione, compilatore, ecc.) Verranno eseguiti più lentamente, perché devono elaborare più dati (e una parte più grande o più piccola di quei dati è rumore).

Se il codice non è organizzato bene, d'altra parte, rovinerà l'analisi statica, il refactoring e qualsiasi altro.

Stai introducendo del rumore nell'input dei tuoi strumenti e sperando che lo affrontino correttamente.

E se il tuo strumento di analisi statica calcola un rapporto commenti / codice? Hai appena sbagliato tutto, con qualcosa di rilevante fino a ieri (o ogni volta che il codice è stato commentato).

Soprattutto, i blocchi di codice commentati introducono ritardi nella comprensione del codice per la manutenzione e l'ulteriore sviluppo e tali ritardi costano quasi sempre molto. Chiediti questo: se hai bisogno di capire l'implementazione di una funzione, cosa preferiresti guardare? due righe di codice in chiaro, o due righe di codice e altre ventisei di commenti che non sono più effettivi?

Il codice può essere utilizzato in futuro

Se lo è, lo troverai nell'SCM scelto dalla tua squadra.

Se utilizzi un SCM competente e fai affidamento su di esso per mantenere il codice morto (invece di ingombrare la fonte), dovresti vedere non solo chi ha cancellato quel codice (autore del commit), ma per quale motivo (messaggio di commit) e quale altro insieme ad esso sono state apportate modifiche (il resto delle differenze per quel commit).

Una volta cancellato, l'autore potrebbe sentirsi a disagio

Così?

Tu sei (presumo) un intero team di sviluppatori che viene pagato per creare il miglior software che sai fare, non "il miglior software che sai fare senza ferire i sentimenti di X".

È una parte della programmazione, che alla fine la maggior parte del codice scritto verrà scartata; per esempio, Joel Spolsky ha detto a un certo punto che per la sua azienda, circa il 2% del codice scritto vede la produzione.

Se dai la priorità all'ego degli sviluppatori rispetto alla qualità del codice di base, sacrificherai la qualità del tuo prodotto, per ... cosa esattamente? Preservare l'immaturità dei tuoi colleghi sviluppatori? Proteggere le aspettative irrealistiche dei tuoi colleghi?

Modifica: ho visto un motivo valido per lasciare il codice commentato nel codice sorgente, ed è un caso molto specifico: quando il codice è scritto in una forma strana / non intuitiva e il modo pulito di riscriverlo non lo fa lavorare per una ragione davvero sottile. Questo dovrebbe essere applicato anche solo dopo che si è tentato ripetutamente di correggere il problema e ogni volta che il tentativo ha reintrodotto lo stesso difetto. In tal caso, è necessario aggiungere il codice intuitivo commentato come commento e spiegare perché non funziona (in modo che i futuri sviluppatori non tenteranno di nuovo la stessa modifica):

// note by <author>: the X parameter here should normally
// be a reference:
// void teleport(dinosaur& X);
// but that would require that we raise another dinosaur and
// kill it every twelve hours
// as such, the parameter is passed by value
void teleport(dinosaur X);

10

Il codice guasto sta inquinando il tuo codice

Il codice morto riduce la comprensibilità e la leggibilità.

I codici migliori vengono sempre riutilizzati e se si hanno codici morti si riduce la riutilizzabilità

Siamo guidati da un approccio modulare di codifica, in cui progettiamo codici per l'interazione con i nostri colleghi programmatori, non per una macchina. Dobbiamo mettere la maggior parte delle energie per facilitare la comprensione del nostro codice. La macchina andrà comunque bene.

Il codice morto o commentato è come falsi segnali di sentiero che confondono solo le persone, quindi evitalo a tutti i costi.


10
  • Paura . Questo fa sì che il team si preoccupi di più e produca di meno. La quantità di paura aumenta in modo esponenziale quando viene introdotto più codice morto. "Non sappiamo se quella punta viene usata, quindi non osiamo rimuoverla o toccarla."
  • Cambiamenti radicali . Se qualcosa che deve essere cambiato ovunque nel sistema esiste anche nel codice morto, lo cambiate? È molto difficile sapere se non è sicuramente usato da qualche parte, quindi è sempre un rischio. E anche se non interrompesse nulla, il codice morto funzionerebbe affatto se venisse ripreso in uso dopo questa modifica?

    Quando si tratta di un cambiamento radicale, gli sviluppatori dovranno anche controllare ogni posto che contiene il codice e nel caso di codice morto questo è ridondante. E controllarli richiede più tempo quando il codice è morto poiché è difficile verificare che non sia utilizzato da nessuna parte.

  • Carico mentale . Ogni volta che devi pensare se qualcosa viene usato o se dovresti fare qualcosa per il codice morto, ci vuole un po 'del tuo potere cerebrale.
  • Inseguimenti dell'oca selvatica . "Ho bisogno di un esempio su come usare Foobar. Oh, è in questi punti del codice base. Controllerò il primo hit e scoprirò dove si trova nell'interfaccia utente. Hmm ... Non riesco a trovarlo da nessuna parte."
  • Report gonfiati (ad es. Quante righe di codice, classi, routine, modifiche). Distorce la visibilità del progetto e le decisioni su quali parti della base di codice dovrebbero essere lavorate e le stime dei progetti futuri.
  • Fiducia indebolita sul codice base . Ciò può comportare più tempo speso per attività ridondanti e interrompe il flusso di utilizzo della base di codice. Gli sviluppatori potrebbero dover controllare con estrema attenzione che tutto ciò che usano funzionerà nel modo in cui pensano che dovrebbe.

È estremamente prezioso se sai che una parte del codice non viene utilizzata perché puoi rimuoverla. Se lo lasci rimanere, in futuro può essere difficile o quasi impossibile essere certi che non venga effettivamente utilizzato. Ad esempio, alcune delle cose che utilizzano il codice in modi sorprendenti: riflessione, chiamate dinamicamente routine concatenate da stringhe, eval, framework magic .

Tuttavia, se c'è un'alta probabilità che il codice venga utilizzato in futuro, è più facile aggiungerlo se è proprio lì lungo l'altro codice invece che nel sistema di controllo della versione. Dopo un po 'potresti non ricordare nessuna parola contenuta nel codice, quindi può essere molto difficile trovare il codice dalle viscere del VCS. Ma lascerei che il codice morto esistesse solo raramente e anche allora commenterei il codice.


4
  • Il codice inutilizzato è uno spazio di ricerca più grande sia da leggere sia da qualsiasi altra cosa che generalmente esegue la scansione del codice. Ad esempio un compilatore, IDE, trova nel file, debug, analisi statica, altro da rivedere, inclusione di file, estrazione da VCS, ecc. Ciò rallenta i processi e aggiunge rumore significativo.
  • Il codice inutilizzato non è sempre codice morto. Può essere eseguito in determinate circostanze. Questo non solo può offrire un vettore per bug e problemi di prestazioni, ma può anche essere un problema di sicurezza. Per quanto riguarda le prestazioni, questo può esprimersi in modi inaspettati come download di dimensioni maggiori.
  • Il codice non utilizzato genera codice inutilizzato. Se elimini una chiamata di funzione e quindi cerchi gli usi di quella funzione per vedere se è ancora necessaria, potresti vedere una corrispondenza dal codice inutilizzato precedente e presumere che puoi mantenerla. Più codice inutilizzato hai, più salti servono per determinare se il codice è inutilizzato.
  • Il codice inutilizzato spesso finisce per dover essere mantenuto. Diciamo che A e B dipendono da C. Di questi, B non viene utilizzato. Si cambia C e quindi B non si compila perché hai rimosso un membro da una struttura in C che B richiedeva, ora devi correggere B o rimuoverlo attivamente dalla compilazione. Avresti dovuto semplicemente rimuoverlo.

Questo elenco potrebbe sembrare semplice ma ognuno di questi si manifesta in centinaia di modi diversi aggiungendo resistenza che sinergizza durante l'intero processo di sviluppo. L'inefficienza può spesso essere dimostrata o dimostrata in modo semplice e matematico.

In risposta ai tuoi punti ...

  • Il codice è già scritto e gli sforzi sono spesi

Ma spesso deve essere mantenuto. Apparirà anche ancora in cose come trova nel file.

  • Il codice può essere testato su un ambiente sintetico e reale

Non sono sicuro di cosa intendi con questo. Penso che sia lo stesso dell'ultimo. Vuoi dire che il codice è già stato testato e ripulirlo potrebbe significare che è necessario ripetere il test. Questo è un costo che di solito ne vale la pena perché ripagherà il 90% del tempo e per evitare che avrebbe dovuto essere pulito prima di entrare in produzione. Quasi tutto il codice ha due iterazioni, fallo funzionare, rendilo pulito. Il motivo è che deve essere testato due volte è perché qualcuno ha saltato l'ultimo passaggio. Se il codice è troppo costoso per leggere il diff, test (cosa che probabilmente è se è disordinato con molto codice inutilizzato), ecc., Allora questo è un altro problema.

  • Se ben organizzato (raggruppato, pacchetto separato, vagamente accoppiato ecc.) Non ti disturba sull'analisi complessiva del codice o sul refactoring

Il tuo codice dovrebbe essere così comunque, ma questo mitiga solo moderatamente il problema. È l'argomento più strano sentire che qualcosa dovrebbe essere organizzato ma impuro. È normale cercare di mantenere il codice modulare e ridurre le dipendenze, ma vuoi anche codice riutilizzabile e se tutti i tuoi moduli sono un'isola è probabile che tu non sia stato DRY. Potresti anche trovarti a fare un disaccoppiamento eccessivo che non fa altro che mitigare il problema del codice disordinato inutilizzato.

  • Il codice può essere utilizzato in futuro

Molte persone apprezzano il codice scritto. Se non viene utilizzato ora è un peso morto e in realtà quando si percorre questo percorso spesso solo una frazione del codice inutilizzato diventa codice utilizzato. Con ogni probabilità è improbabile che il codice inutilizzato sia codice utilizzabile o utilizzato. Il codice più probabile da riutilizzare è già codice utilizzato che sta facendo qualcosa.

Quel che è peggio è che il codice inutilizzato non ha uno scopo. Quando qualcuno arriva e deve cambiare qualcosa che finisce per avere un impatto sul codice inutilizzato, rimarrà perplesso seduto lì a cercare di capire cosa deve fare questo codice inutilizzato senza scopo.

È facile per le persone sentirsi così all'inizio, poiché il codice richiede molto impegno. Tuttavia, una volta fluente e abituato al codice diventa come andare in bicicletta. Scoprirai che il costo per scrivere un tale pezzo di codice precipita, il costo per mantenerlo aumenta.

  • Una volta cancellato, l'autore potrebbe sentirsi a disagio

Questo è il problema dell'autore. Da un lato è egoista lasciare in giro un sacco di codice inutilizzato perché gli altri abbiano a che fare. D'altro canto, se un autore mette i propri sentimenti sulla qualità del codice, probabilmente non dovrebbe scrivere codice. Vai giù per la strada con questo di non puoi aggiustare il loro codice quando è rotto perché ferirà i loro sentimenti. Non è un buon segno se qualcuno è attaccato al codice semplicemente perché è suo piuttosto che perché è buono. Un autore dovrebbe essere felice della pulizia del codice. È come se qualcuno tirasse fuori la spazzatura per te e la gettasse nel cestino.

Sarei al settimo cielo se qualcuno lo facesse per me. Ciò che potrebbe rendere più facile superare quei sentimenti è invece di aspettare che qualcun altro lo faccia, prova a farlo da solo. Continua a riscrivere in modo iterativo una parte di codice che hai fatto, migliorandone le prestazioni, spostandoti in modo conciso, con meno eccessi e più flessibile ma con meno codice ogni volta. Cerca di non sentirti a tuo agio con la quantità di codice ma quanto puoi ottenere con un codice per quanto piccolo. Questo è macinare per salire di livello e una volta fatto tutto il tuo codice uscirà a un buon livello successivo, quindi non avrà bisogno di essere livellato così spesso.


3

Prima di tutto dovresti sempre usare uno strumento di controllo del codice sorgente per gestire i tuoi progetti e quindi rimuovere il codice inutilizzato è una buona pratica in quanto puoi sempre tornare indietro usando il controllo del codice sorgente per ottenere il codice rimosso. Per me il motivo per rimuovere il codice inutilizzato è che solo la persona che sa che il codice non è utilizzato lo sa, qualcun altro nel team si imbatterà in quel codice e proverà a capire cosa fa e come si adatta all'intera applicazione e si sentirà deluso dopo così tanti sforzi che il codice non viene utilizzato affatto :)


3

Questa discussione è vecchia di diversi anni, ma mi sono imbattuto in esso ...

Una cosa che non ho visto menzionato è il lavoro che deve essere sostenuto per rimuovere il codice inutilizzato. In molti casi, il tempo e gli sforzi per rimuovere il codice inutilizzato non sono di natura banale, inoltre ci sono tipicamente costi aggiuntivi per testare e documentare il sistema refactoring. Solo un'altra cosa da considerare nel processo decisionale.


2

Penso che tu possa avere due casi: - codice dell'applicazione: se non viene utilizzato forse non è stato testato e non è stato mantenuto nel tempo, forse puoi passare a un "repository di codice interno" - codice API: se stai scrivendo una libreria, IMHO è una scelta migliore per mantenerlo ma all'interno del tuo processo di sviluppo attivo


2

Sei sicuro che il codice non sia utilizzato?

Non è sufficiente controllare che il codice venga comunque compilato. In C ++, se rimuovi un metodo definito implicitamente "inutilizzato" come operator=se non avessi intenzione di ottenere un errore del compilatore, la classe inizierà silenziosamente a utilizzare un'implementazione predefinita (potenzialmente errata). In Java o C # il codice potrebbe essere utilizzato tramite reflection. Nei linguaggi orientati agli oggetti, l'ereditarietà può svolgere un ruolo (la classe base può ora essere chiamata). In quasi tutte le lingue, potrebbe aver preso il sopravvento un'altra funzione sovraccarica.

Controlla l'età del codice nel controllo della versione, non solo se è inutilizzato. Ho visto codice che sembrava inutilizzato ma era stato appena eseguito il commit, ed è stato effettivamente il primo passo nel progetto di un altro sviluppatore.

Rimuovere in modo aggressivo il codice inutilizzato

Paghi per mantenere il codice:

  • Correzione di build danneggiate (tempo di progettazione). Recentemente abbiamo avuto una complicata catena di #includecambiamenti, che ha introdotto un nuovo sovraccarico per il codice inutilizzato, portando a un mal di testa di dimensioni ragionevoli per ogni ingegnere di un team di dozzine di sviluppatori.
  • Nelle risorse della macchina sui test (supponendo che si disponga di build continue di auto-test). Il mio team ha recentemente esaminato tutti i nostri test più lenti e molti di essi erano basati su codice altrimenti inutilizzato. Gli ingegneri che eseguono test in locale o come parte dell'integrazione continua sono in attesa di test su codice inutilizzato.
  • In termini di leggibilità (ancora tempo di ingegneria). I tuoi file di intestazione rappresentano un'API. Se includono funzioni che nessuno vorrebbe usare ma tutti devono leggere, la curva di apprendimento del tuo codice è molto più difficile.
  • Nelle ricerche di codice (di nuovo tempo di ingegneria). Puliresti la tua casa, il tuo disco rigido o Google Drive? Più si effettua la ricerca in un dominio, più è importante che abbia contenuti pertinenti per evitare falsi positivi (o si utilizza una ricerca più sofisticata come un motore di ricerca web).

Direi che essenzialmente tutto il codice che lo sviluppatore medio scrive diventa inutilizzato su un orizzonte di cinque anni, quindi questa attività non si ferma mai . Non lasciare che questo sia te; scrivere solo codice di alta qualità e assolutamente necessario.

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.