Quante righe per classe sono troppe in Java? [chiuso]


74

Nella tua esperienza, qual è una regola empirica utile per quante righe di codice sono troppe per una classe in Java?

Per essere chiari, so che il numero di righe non è nemmeno vicino allo standard reale da utilizzare per ciò che dovrebbe essere in una particolare classe e cosa non dovrebbe. Le lezioni dovrebbero essere progettate secondo le filosofie OOP appropriate (incapsulamento, ecc.) In mente. Detto questo, una regola empirica potrebbe fornire un utile punto di partenza per considerazioni di refactoring (es. "Hmmm, questa classe ha> n righe di codice; è probabilmente illeggibile e fa un pessimo lavoro di incapsulamento, quindi potrei voler vedere se dovrebbe essere refactored ad un certo punto ").

Il rovescio della medaglia, forse hai incontrato esempi di classi molto grandi che obbedivano ancora bene al design OOP ed erano leggibili e mantenibili nonostante la loro lunghezza?

Ecco una domanda correlata, non duplicata, sulle righe per funzione .


4
Ho visto lezioni con più di mille righe, non credo che ci siano "troppe".
Mahmoud Hossam,

5
Sono troppi quando non verranno più compilati. Seriamente, sono troppi quando la classe sta facendo troppe cose diverse.
Berin Loritsch,

20
Una regola empirica si trasforma in un massimo che si trasforma in una politica che si trasforma in un disaccordo. Evita la numerosità. Il conteggio e la misurazione non sono il modo ideale per stabilire se le responsabilità sono state assegnate correttamente.
S.Lott

7
Quasi uguale al numero corretto di pollici per un pezzo di corda.
Matt

6
Una domanda con 30 voti, visualizzata ~ 24k volte, 10 risposte con (collettivamente) ~ 75 voti. "chiuso come principalmente basato sull'opinione" Benvenuto nello scambio di stack :) Qualcosa deve cambiare nella cultura SE ...
jb.

Risposte:


79

Alcune metriche interessanti:

            junit fitnesse testNG tam jdepend ant tomcat
            ----- -------- ------ --- ------- --- ------
max 500 498 1450 355 668 2168 5457
media 64,0 77,6 62,7 95,3 128,8 215,9 261,6
min 4 6 4 10 20 3 12
sigma 75 76 110 78 129 261 369
file 90 632 1152 69 55 954 1468
linee totali 5756 49063 72273 6575 7085 206001 384026

Uso FitNesse come punto di riferimento perché avevo molto a che fare con la sua scrittura. In FitNesse la classe media è lunga 77 linee. Nessuno è più lungo di 498 linee. E la deviazione standard è di 76 righe. Ciò significa che la stragrande maggioranza delle classi sono meno di 150 righe. Anche Tomcat, che ha una classe superiore a 5000 linee, ha la maggior parte delle classi meno di 500 linee.

Detto questo, probabilmente possiamo usare 200 linee come buona linea guida per rimanere al di sotto.


9
Se la classe ha una sola responsabilità, le probabilità che vada oltre le 200-500 linee sono piuttosto scarse. Quelli che hanno in genere "classi interne" per gestire altre responsabilità correlate . Ad esempio, la classe di linea Tomcat 5000+ potrebbe essere in realtà 1 classe principale con una dozzina di classi interne. Questo non è insolito in Java dove hai gestori di richieste e simili.
Berin Loritsch,

4
come si ottengono queste metriche, davvero? voglio solo sapere
Sнаđошƒаӽ

1
Di solito mi rivolgo più a questa risposta sulla domanda collegata relativa alle funzioni: programmers.stackexchange.com/a/9452/100669 LOC è in qualche modo irrilevante, tranne per il fatto che forse una regola empirica estremamente generale per iniziare semplicemente a chiedermi se potresti essere in grado di scomporre ulteriormente le cose. E sono d'accordo sulla cosa delle classi nidificate. Tuttavia, 500 è probabilmente più vicino a un segnale di avvertimento generale.
Panzercrisis,

@ Sнаđошƒаӽ github.com/AlDanial/cloc
firephil

32

Per me, le linee di codice sono irrilevanti in questo contesto. Riguarda il numero di diversi motivi per cui vorrei venire in questa classe per cambiarlo.

Se vorrei venire in questa classe quando voglio cambiare le regole per la convalida di una persona, non voglio venire nella stessa classe per cambiare le regole per la convalida di un ordine, né voglio venire qui per cambiare dove persistere una persona.

Detto questo, se miri a ciò, raramente troverai classi più di 200 righe. Accadranno, per validi motivi, ma saranno rari. Quindi, se stai cercando una metrica con bandiera rossa, non è un brutto punto di partenza; ma renderlo una linea guida, non una regola.


200 sembra giusto come un'ipotesi molto approssimativa. Come dici tu, non la cosa di cui ti preoccupi prima però.
Steve,

L'altro aspetto di Java è che, contando i LOC, ignorerei i getter / setter.
MrFox,

1
@MrFox: non sono d'accordo. Se la tua classe ha abbastanza getter e setter per inclinare i dati LOC, ciò conta contro di essi nel "questa classe sta facendo troppo?" domanda. Tuttavia, come compromesso sarei disposto a getter / setter NetBean a meno di 1 linea / linea per rispetto per l'eccessiva piastra di caldaia che hanno questi metodi.
Brian

23

Mi dispiace ma sono molto sorpreso che molte risposte affermino che "non ha molta importanza". È MOLTO importante quante linee ci sono in una classe. Perché? Considera questi principi nello scrivere un buon codice Java ...

  • testabilità
  • Coesione
  • accoppiamento
  • Comprensibilità

Le classi con molte righe violano molto probabilmente tutti questi principi.

Per coloro che hanno affermato che "non ha molta importanza" ... quanto è stato divertente per te provare a capire una classe che ha più di 5000 righe? Oppure, per modificarlo? Se dici che è divertente, hai una strana affinità con il dolore ...

Direi che ogni classe che contiene più di 1000 righe dovrebbe almeno essere messa in discussione su come potrebbero violare i principi sopra e possibilmente analizzata in diverse classi "off-shoot".

I miei commenti si basano sulla lettura e lo studio di autori come Martin Fowler, Joshua Bloch e Misko Hevery. Sono eccellenti risorse da consultare per la scrittura di un buon codice Java.

Fai un favore al prossimo (che potresti essere tu tra un paio d'anni) e sforzati di scrivere lezioni con meno righe anziché più righe.


Penso che tutti siano d'accordo sul fatto che 5000+ non sono generalmente un buon segno (senza contare le classi nidificate), ma pensano che sia più un effetto collaterale o qualcosa del vero problema. Certo, alcune persone sono eccessivamente prolisse e usano un numero eccessivo di righe solo per dichiarare e inizializzare variabili e simili - e devono fermarlo. Questo lo rende meno leggibile. Ma se si riferisce alla struttura delle classi, il problema non è il LOC stesso; è il fatto che qualcuno non sta semplicemente rompendo le cose molto bene per cominciare, e il LOC ne è un effetto collaterale.
Panzercrisis,

2
Il punto è che una classe dovrebbe avere un'elevata coesione e una chiara responsabilità, il che significa che le classi di solito non crescono così grandi. Ma se una classe è ben progettata ma ha ancora più di 5000 righe di codice, non aiuta nessuno a dividerla in più classi più ristrette.
Jacques B

12

Dipende dalla complessità, non dal numero di linee. Ho scritto grandi routine stupide che erano facili da capire e che hanno fatto esattamente una cosa e l'hanno fatto bene, ma sono andate avanti per centinaia di righe. Ho scritto funzioni abbastanza brevi che erano difficili da capire (e il debug).

Un'altra cosa che potresti guardare è il numero di funzioni pubbliche in una classe. Questo può anche essere un segnale di avvertimento.

Non ho buoni conteggi disponibili, ma suggerirei di cercare un codice decente che faccia cose utili nel tuo negozio e basarlo su quello. Certamente dovresti guardare alle classi più lunghe e alle API più grandi.


7
+1: non misurare cose stupide come le linee. Complessità ciclistica e conteggi delle caratteristiche (numero di metodi) hanno più senso le linee.
S.Lott

2
sì e no. Un numero eccessivo di linee è spesso un sintomo di cattiva progettazione, e quindi una bandiera rossa che probabilmente la classe necessita di refactoring.
jwenting

1
@jwenting Sì, è quello a cui stavo arrivando. Conosco molte linee! = Deve essere refactored, ma quasi tutte le classi con cui sto lavorando che hanno davvero bisogno di essere refactored a causa del design scadente hanno molte linee.
Michael McGowan,

5

Ci sono troppe righe di codice se la classe sta facendo troppe cose diverse. In sostanza, se segui il principio della responsabilità singola per le classi, c'è un limite a quanto crescerà la classe.

Per quanto riguarda le limitazioni fisiche che puoi avere (fonte: formato file Class Java5 ):

  • 65.536 costanti, interfacce applicate, campi, metodi e attributi - ciascuno. NOTA: rimarrà a corto di spazio costante prima di esaurire uno qualsiasi degli altri elementi. NOTA 2: gli attributi sono costrutti di file di classe - da non confondere con i marcatori '@Attribute' (ovvero le informazioni di debug e il codice byte sono memorizzati come attributi separati per un metodo).
  • Ciascun metodo può contenere 4 GB (32 bit) di codice byte generato. NOTA: le versioni Java precedenti alla 1.5 potevano contenere solo 64 KB (16 bit) di codice byte generato per ciascun metodo.

In breve, il file di classe può essere molto più grande di quanto chiunque ritenga utile. Se ti attieni al principio della responsabilità singola, i tuoi file di classe avranno la giusta dimensione.


1
+1 per singola responsabilità :) @Berin lo implementi rigorosamente nel tuo software?
Aditya P,

Sì. Il trucco è dividere le responsabilità in modo sensato.
Berin Loritsch,

ah, il buon vecchio confine da 64 KB. Bel test di Lithmus per vedere se i tuoi JSP sono troppo complessi, poiché vengono tradotti in un unico metodo con molte istruzioni println per tutto il tuo html statico :)
jwenting

A partire da Java 5, l'hanno aumentato a 4 GB. Non ci sono preoccupazioni adesso.
Berin Loritsch,

5

La risposta corretta è 42. Sto solo scherzando.
In realtà, il numero massimo di righe consigliate per classe è di 2000 righe.

Le "Convenzioni del codice Java" dal 1999 lo affermano in questo modo: i
file più lunghi di 2000 righe sono ingombranti e dovrebbero essere evitati.

Dopo aver seguito le convenzioni di codifica Sun / Oracle dall'invenzione di Java, ho trovato ragionevole questa regola empirica sulle linee per classe. Il 99% del tuo codice Java dovrebbe essere conforme ... E se va oltre il 2000, metti un TODO in cima dicendo che la classe ha bisogno di lavoro.

La cosa peggiore è il caso contrario quando i programmatori creano troppe piccole classi con quasi nessuna reale funzionalità in ogni classe. Ignorando il consiglio di "Favorire la composizione", i programmatori creano centinaia di classi ereditarie che creano modelli di oggetti complicati che sono di gran lunga peggiori del problema delle classi di grandi dimensioni (che almeno mantengono la funzionalità con un nome di classe pertinente).

http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-141855.html#3043


In realtà, molti di loro sono commenti @LluisMartinez
Xtreme Biker

Non sono assolutamente d'accordo con il 2000 . Una classe non deve superare le 200 righe, esclusi i commenti.
Nikolas

4

Codice pulito:

Le lezioni dovrebbero essere piccole!

La prima regola delle classi è che dovrebbero essere piccoli. La seconda regola delle classi è che dovrebbero essere più piccoli di così. No, non ripeteremo esattamente lo stesso testo del capitolo Funzioni. Ma come per le funzioni, più piccola è la regola principale quando si tratta di progettare classi. Come per le funzioni, la nostra domanda immediata è sempre "Quanto piccolo?"

** Con le funzioni abbiamo misurato le dimensioni contando le linee fisiche. Con le classi utilizziamo una misura diversa. Contiamo le responsabilità. **

Il nome di una classe dovrebbe descrivere quali responsabilità adempie. In effetti, la denominazione è probabilmente il primo modo per aiutare a determinare la dimensione della classe. Se non riusciamo a ricavare un nome conciso per una classe, probabilmente è troppo grande. Più il nome della classe è ambiguo, più è probabile che abbia troppe responsabilità. Ad esempio, i nomi delle classi che includono parole donnole come Processore o Manager o Super suggeriscono spesso sfortunate aggregazioni di responsabilità.

Poi:

  • Assicurati solo che i tuoi metodi facciano solo una cosa.
  • Quindi assicurati che la classe non abbia troppe responsabilità.

Ti ritroverai con una classe di dimensioni gestibili.


se Clean Codein cima alla tua risposta si riferisce al libro di Robert C. Martin (che fa!), allora devo dirti e lo ho in comune; quel libro è ciò che mi ha portato a questa domanda. Penso che questa risposta dica tutto
Sнаđошƒаӽ

2

Il numero di linee è una metrica piuttosto scadente per la qualità della classe. Per me, mi piace guardare (come altri hanno già detto) i metodi pubblici, nonché tutte le proprietà esposte pubblicamente (immagino che i getter / setter pubblici in Java). Se dovessi estrarre un numero dall'aria per quando potrebbe attirare la mia attenzione, direi quando ce ne sono più di 10. Davvero, se è più di circa 5 delle proprietà o dei metodi, darò un'occhiata e troverò spesso modi per fare il refactoring, ma qualsiasi cosa sopra i 10 è di solito un segnale di avvertimento che è probabile che qualcosa sia scarsamente esposto.

È un'altra conversazione del tutto, ma i metodi e i campi privati ​​hanno meno odore per me, quindi se stanno contribuendo molto al numero di righe, allora potrei non essere così preoccupato. Per lo meno, mostra che probabilmente non esiste un controller di Dio che manipola l'oggetto da lontano, il che è un bel problema di progettazione.


2

Prova a utilizzare una metrica migliore.

Un esempio è la metrica ABC . È più una misura di quanto lavoro viene svolto dal codice rispetto a quanto codice c'è.


1

Ogni riga che rientra nel dominio problematico della tua classe scritto al di fuori della classe è una riga in meno e una in più nella classe in cui vive. Pensa a una lezione come a un argomento. Devi coprirlo. Il più conciso possibile è l'ideale, ma se ci vogliono 500 linee, ci vogliono 500 linee. Se 100 di quelle righe coprono un altro argomento, appartengono a un'altra parte. Rompere i sottodomini più piccoli all'interno della classe come lezioni interne ha senso, ma definirei quelli al di fuori della classe solo se fossero utilizzati altrove.

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.