In quale punto / intervallo un file di codice è troppo grande?


36

Sto trovando un sacco di file di 2-3k line e non mi sembra che dovrebbero essere così grandi.

Qual è un buon criterio per chiamare obiettivamente un file di codice sorgente "troppo grande"? Esiste una quantità massima di righe che un file di codice sorgente dovrebbe avere?


Il tuo peer ti dice dopo aver esaminato il codice. "Non puoi determinarlo da solo perché conosci più l'autore di quanto il codice non dica da solo. Un computer non può dirti, per le stesse ragioni per cui non è in grado di dire se un dipinto è arte o no. Quindi, hai bisogno di un'altra persona capace di mantenere il software - per vedere cosa hai scritto e dare la sua opinione ... "
moscerino

Alcuni compilatori avevano strani limiti sulla dimensione del codice sorgente: lunghezza massima della linea o numero massimo di righe. Quando il compilatore si lamenta, questo è un indicatore oggettivo che il codice è troppo grande (o che è tempo di aggiornare).
mouviciel,

2
Dividi il più possibile, ma senza interrompere l'integrità dei file. Ogni file (o coppia di file header / sorgente) dovrebbe essere sempre un insieme arrotondato, indipendentemente dall'implementazione interna di altri file. Se questo significa che alcuni file saranno grandi perché implementano qualcosa di complesso, così sia.
Ambroz Bizjak,

Nota che la complessità non riguarda solo i numeri, ma anche la struttura. Ad esempio, vorrei dichiarare lo zen di Python "flat is better of nided": un elenco semplice di 100 casi è più semplice di una gerarchia (non ricorderai tutti i 100 casi ma ricorderai facilmente che ci sono 100 alternative) . E una gerarchia "normale" in cui i rami hanno la stessa struttura dei loro fratelli sono più semplici della gerarchia con sottostruttura irregolare.
Giovedì

"È quello il codice sorgente?" "No, questo è il makefile, il codice sorgente è nei camion che seguono dietro".
mckenzm,

Risposte:


26

Come modello ideale utilizzo i seguenti criteri (con una logica simile a quella suggerita da Martin Beckett, ovvero pensare in termini di struttura logica e non in termini di righe di codice):

Regola 1

Una classe per file (in C ++: una classe -> un'intestazione e un file di implementazione).

Regola 2

Sette è considerato il numero di elementi che il nostro cervello può osservare contemporaneamente senza confondersi. Sopra 7 troviamo difficile tenere una visione d'insieme di ciò che vediamo. Pertanto: ogni classe non dovrebbe avere più di 7-10 metodi. Una classe che ha più di 10 metodi è probabilmente troppo complessa e dovresti provare a dividerlo. La divisione è un metodo molto efficace perché ogni volta che dividi una classe riduci la complessità di ogni singola classe almeno di un fattore 2.

Regola 3

Un corpo del metodo che non si adatta a una o due schermate è troppo grande (suppongo che una finestra di schermo / editor sia di circa 50 righe). Idealmente, puoi vedere l'intero metodo in una finestra. In caso contrario, è sufficiente scorrere un po 'su e giù, senza dimenticare la parte del metodo che viene nascosta. Quindi, se devi scorrere più di una schermata verso l'alto o verso il basso per leggere l'intero corpo del metodo, il tuo metodo è probabilmente troppo grande e puoi facilmente perdere la panoramica.

Ancora una volta, suddividere i metodi usando i metodi di aiuto privati ​​può ridurre la complessità del metodo molto rapidamente (ad ogni divisione la complessità è almeno dimezzata). Se introduci troppi metodi di aiuto privati, puoi prendere in considerazione la creazione di una classe separata per collezionarli (se hai più metodi privati ​​di quelli pubblici, forse una seconda classe si nasconde all'interno della tua classe principale).

Mettendo insieme queste stime molto approssimative:

  • Al massimo una classe per file di origine.
  • Al massimo 10 metodo pubblico per classe.
  • Al massimo 10 metodi privati ​​per classe.
  • Al massimo 100 righe per metodo.

Quindi un file sorgente che è più di 2000 righe è probabilmente troppo grande e inizia a essere troppo disordinato.

Questa è davvero una stima molto approssimativa e non seguo questi criteri in modo sistematico (soprattutto perché non c'è sempre abbastanza tempo per eseguire il refactoring adeguato). Inoltre, come ha suggerito Martin Beckett, ci sono situazioni in cui una classe è una grande raccolta di metodi e non ha senso dividerli in modo artificiale solo per ridurne la classe.

Ad ogni modo, nella mia esperienza un file inizia a diventare illeggibile quando uno dei parametri sopra non viene rispettato (ad esempio un corpo del metodo di 300 righe che si estende su sei schermate o un file sorgente con 5000 righe di codice).


1
Vorrei anche cercare metodi non più di 10 righe ... aiuta con leggibilità / comprensione di ciò che il metodo sta facendo e riduce la complessità che può facilmente accadere in grandi metodi ...
Zack Macomber

4
La Regola2 è assurda se la segui fino alla sua conclusione. Non dovresti avere più di 7 file in una directory, quindi devi mantenerli grandi in modo da non confonderti tra le decine o le centinaia di file nel tuo progetto. Allo stesso modo, una struttura di directory profondamente annidata è eccessivamente confusa, quindi è meglio tenere alcuni file di grandi dimensioni in una directory piuttosto che spargere tutto.
hasen

1
Mi dispiace che questa risposta si basi su metriche totalmente arbitrarie. I "7 articoli" sono chiaramente cazzate, altrimenti non saresti in grado di usare l'alfabeto. La dimensione dell'oggetto dovrebbe essere basata sulla separazione delle preoccupazioni, responsabilità singola, alta coesione-basso-accoppiamento e principi simili, non numeri arbitrari.
Jacques B

1
@JacquesB I 7 articoli sono generalmente indicativi di 7 pezzi di informazioni non correlate. Se il tuo cervello è in grado di associare o raggruppare informazioni, in un certo senso è 1 informazione che può portare a più se tenti di ricordare (in realtà "alfabeto" è un simbolo, non tutte le 26 lettere). Un esempio migliore sarebbe provare a ricordare un numero di 7 cifre che ti è stato detto al telefono senza avere carta e penna disponibili. I metodi chiaramente non sono numeri arbitrari, ma se tali metodi sono rilevanti per ciò che stai codificando, puoi aspettarti dopo 7, dovrai cercarlo prima di poter richiamare correttamente.
Neil,

3
@Neil: se i metodi in una classe sono informazioni casuali non correlate, allora hai problemi più grandi nella progettazione della classe rispetto al numero di metodi.
Jacques B

33

No, non in termini di righe di codice. Il driver dovrebbe essere un raggruppamento logico. Ad esempio, non dovrebbero esserci più classi in un unico file di grandi dimensioni

Se avessi una classe che aveva legittimamente qualche centinaio di metodi (non impossibile nel dire la modellazione 3D) sarebbe molto meno conveniente dividerlo in file arbitrari. In passato dovevamo farlo quando la memoria era più scarsa e i processori più lenti - ed era una seccatura, alla costante ricerca della definizione della funzione.


2
Una classe con centinaia di metodi non sarebbe sintomo di invidia di classe, mancanza di coesione, cattiva progettazione, violazione del principio della responsabilità singola, ecc.?
Tulains Córdova,

2
@ user1598390: di solito, ma non sempre.
whatsisname

4
@ user1598390 - comune nella modellazione gis / 3d per avere un sacco di operazioni che è possibile eseguire e quindi sovraccaricarle per il segnale 2d, 3d, 4d, 3d +, quindi float / double / integer ecc. - i modelli aiutano un po 'ma per l'efficacia molte operazioni sono spesso migliori di una bella gerarchia di classe
Martin Beckett,

2
@ tp1 - e usi un carattere piccolo in modo che non occupino tanto spazio?
Martin Beckett,

2
@ tp1 Amico, mi dispiace, davvero non intendo alcuna mancanza di rispetto, ma mi dispiace per chi lavora con te. Se hai 1200 classi, usa una convenzione di directory, se hai troppe directory, suddividile in moduli / librerie indipendenti.
dukeofgaming,

8

Quando il codice in esso diventa non mantenibile. cioè: non puoi dire semplicemente guardando il codice se il metodo / classe / funzione che stai cercando (e devi modificare / eseguire il debug) è lì dentro o no, e se sì, dove si trova.

Tuttavia, la scelta e le funzionalità dell'IDE / editor influenzeranno la quantificazione effettiva di questo limite superiore. Raggruppamento del codice , la funzione / metodo di messa in vendita, e la ricerca sarà ritardare il momento questo sviluppo presenta scenario.

Ma quando lo fa, è il momento di dividerlo.


2

Ecco una vista alternativa: stai chiedendo come limitare la dimensione del file. La mia opinione è che ci sono molti fattori che rendono molto problematici i file di codice di grandi dimensioni. A volte il file di codice è enorme ma il suo contenuto è ben raggruppato ed estremamente pulito, in modo che le dimensioni non causino problemi significativi. Ho visto molti file che sono molto leggibili nonostante l'alto LOC.

Invece di toccare la metrica LOC, preferirei usare i dati della cronologia per capire con quale frequenza il codice viene rotto in quei file di grandi dimensioni. Di solito la ragione di ciò è che gli sviluppatori non hanno il tempo di pazientare di controllare le altre posizioni pertinenti nello stesso file e apportare le modifiche con mentalità "correzione rapida" senza sufficiente comprensione.

Il pericolo maggiore è la presenza di codice copia-incolla. La codifica copia-incolla naturalmente accelera anche la crescita di LOC. Penso che eliminare il copia-incolla sia ancora più importante che mantenere LOC sotto un numero magico. Oltre al puro copia-incolla, c'è anche un secondo pericolo nei file di grandi dimensioni: funzionalità sovrapposte. Più è grande il file, più è probabile che si finisca per reimplementare un frammento che si trova già in un'altra sezione dello stesso file.

Quindi, fintanto che il rapporto di bug fix (rapporto di commit bug fix per tutti i commit) è basso per i file più grandi, la situazione è tollerabile. Si prega di provare git logper esso e sfogliare quanti dei commit sono legati a errori. Oppure utilizza uno strumento in grado di analizzarlo e visualizzarlo automaticamente, ad esempio Softagram .


-1

Considera questo Metaphor. Quando si tratta di lunghezza del codice, penso che dovremmo considerare quanto segue:

The Cat in The Hat (50 pp.)

e

Lord of The Rings (1,178 pp.)

Non c'è niente di sbagliato in Lord of the Rings. È un libro favoloso. The Cat in the Hatè anche un ottimo libro. Entrambi possono essere compresi da un bambino di 5 anni, ma solo uno è più adatto a causa del contenuto.

A mio avviso, scrivere codice dovrebbe avere senso per un bambino di 5 anni ogni volta che possiamo. Cyclomatic Complexityè un concetto importante che gli sviluppatori dovrebbero prendere in considerazione quando generano codice. Utilizzo e creazione di librerie per migliorare il più possibile la funzionalità e la riusabilità del codice. In questo modo il nostro codice può parlare più volumi di quello che vediamo scritto.

La maggior parte di noi non sta scrivendo il codice assembly . Ma la radice del nostro codice è assembly. La ricerca tra 10000 linee di assemblaggio è più difficile di 10000 linee di Python, se eseguita correttamente.

Ma alcuni lavori richiedono la scrittura da 500 a 1000 righe. Il nostro obiettivo con il codice dovrebbe essere quello di scrivere 300 righe di codice pulito.

Come sviluppatori, vogliamo scrivere "Il Signore degli Anelli". Fino a quando non avremo un bug e avremmo voluto scrivere "Cat in the Hat". Non rendere la codifica una misura dell'ego. Basta far funzionare le cose in modo semplice.

Gli sviluppatori non vogliono documentare il codice (adoro il codice documentato personalmente, non sono egoista). Quindi non scrivere codice che solo tu puoi capire / leggere. Scrivi il Cat in the Hatcodice

Sappiamo tutti che sei JRR Tolken (nella tua testa). Ricorda che non avrai nulla da dimostrare con il codice privo di bug.

Un altro motivo per la metafora.

Non esagerare con il lettore diffondere la ricchezza. Se lavori con un gruppo di persone e tutti devono cambiare lo stesso file di grandi dimensioni, probabilmente ti stai mettendo in un gitinferno.

Tutti adorano il rebasing.

-> Nessuno ha mai detto!

TL; DR Focus sulla leggibilità. Distribuisci il tuo codice e supporto su più righe e file il più possibile. Non gettare 8 o 9 classi in un singolo file, rende il codice difficile da leggere e difficile da mantenere. Se si dispone di un codice o loop di condizioni di grandi dimensioni, prendere in considerazione la possibilità di modificarli in Lambdas se la lingua lo supporta. Le funzioni dei servizi di pubblica utilità dovrebbero essere considerate un'ottima strada per aumentare la leggibilità del codice. Evitare nidificazione pesante.


Non un downvoter, ma la tua analogia è un po 'persa su di me. Stai dicendo che è meglio distribuire il codice su più righe e avere meno parole su ogni riga?
Foraggio l'

Distribuisci il codice e l'helper su più righe e file il più possibile. Concentrati sulla leggibilità. Non lanciare 8 o 9 classi in un singolo file. Rende il codice difficile da leggere e più difficile da mantenere. Se si dispone di un codice condizione grande o di loop. Trasformali in utility. Evitare nidificazione pesante. Per favore fatemi sapere se questo aiuta a spiegarlo.
GetBackerZ

Forse dovresti modificarlo nella tua risposta, poiché ciò renderebbe più chiaro ciò che intendi.
Foraggio

Ho usato la sceneggiatura di Jackie Brown come parametro per i programmi COBOL modulari di z / OS. Sai, per le battute sui cocktail party ...
Mckenzm,

"dare un senso a un bambino di 5 anni ogni volta che possiamo." - per problemi del mondo reale che pagano le bollette, questo è raramente possibile e punta alla cosa sbagliata
chiama
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.