¿Cuántas líneas por clase son demasiadas en Java? [cerrado]

74

En su experiencia, ¿cuál es una regla práctica útil para cuántas líneas de código son demasiadas para una clase en Java?

Para que quede claro, sé que el número de líneas ni siquiera se acerca al estándar real para lo que debería estar en una clase en particular y lo que no debería. Las clases deben diseñarse de acuerdo con las filosofías apropiadas de OOP (encapsulación, etc.) en mente. Dicho esto, una regla general podría proporcionar un punto de partida útil para consideraciones de refactorización (es decir, "Hmmm, esta clase tiene> n líneas de código; probablemente sea ilegible y esté haciendo un mal trabajo de encapsulación, por lo que me gustaría ver si debería ser refactorizado en algún momento ").

Por otro lado, ¿tal vez has encontrado ejemplos de clases muy grandes que todavía obedecían bien al diseño OOP y que eran legibles y mantenibles a pesar de su longitud?

Aquí hay una pregunta relacionada, no duplicada , sobre líneas por función .

Michael McGowan
fuente
44
He visto clases con más de mil líneas, no creo que haya "demasiadas".
Mahmoud Hossam
55
Son demasiados cuando ya no se compilan. En serio, son demasiados cuando la clase está haciendo demasiadas cosas diferentes.
Berin Loritsch
20
Una regla general se convierte en un máximo que se convierte en una política que se convierte en un desacuerdo. Evita la numerosidad. Contar y medir no son la forma ideal de establecer si las responsabilidades se asignaron correctamente.
S.Lott
77
Casi lo mismo que el número correcto de pulgadas para un trozo de cuerda.
Matt
66
Una pregunta con 30 votos, vista ~ 24k veces, 10 respuestas con (colectivamente) ~ 75 votos. "cerrado como principalmente basado en la opinión" Bienvenido a stack exchange :) Algo debe cambiar en la cultura de SE ...
jb.

Respuestas:

79

Algunas métricas interesantes:

            prueba de fitnesse de junit NG tam jdepend ant tomcat
            ----- -------- ------ --- ------- --- ------
max 500498 1450355668 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
expedientes 90632 1152 69 55954 1468
líneas totales 5756 49063 72273 6575 7085 206001 384026

Utilizo FitNesse como punto de referencia porque tenía mucho que ver con escribirlo. En FitNesse, la clase promedio tiene 77 líneas de largo. Ninguno tiene más de 498 líneas. Y la desviación estándar es de 76 líneas. Eso significa que la gran mayoría de las clases son menos de 150 líneas. Incluso Tomcat, que tiene una clase en exceso de 5000 líneas, tiene la mayoría de las clases de menos de 500 líneas.

Dado esto, probablemente podamos usar 200 líneas como una buena guía para permanecer debajo.

Tío Bob.
fuente
9
Si la clase solo tiene una responsabilidad, las posibilidades de que supere las 200-500 líneas son bastante escasas. Los que normalmente tienen "clases internas" para manejar otras responsabilidades relacionadas . Por ejemplo, la clase de línea Tomcat 5000+ podría ser realmente una clase principal con una docena de clases internas. Eso no es inusual en Java donde tiene manejadores de solicitudes y demás.
Berin Loritsch
44
¿Cómo se obtienen realmente estas métricas? solo quiero saber
Sнаđошƒаӽ
1
Por lo general, me inclino más hacia esta respuesta en la pregunta vinculada relacionada con las funciones: programmers.stackexchange.com/a/9452/100669 LOC es algo irrelevante, excepto como una regla general extremadamente simple para comenzar a preguntarse si podría ser capaz de descomponer las cosas aún más. Y estoy de acuerdo con lo de las clases anidadas. No obstante, 500 probablemente esté más cerca de una señal de advertencia general.
Panzercrisis
@ Sнаđошƒаӽ github.com/AlDanial/cloc
firephil
32

Para mí, las líneas de código son irrelevantes en este contexto. Se trata de la cantidad de razones diferentes por las que vendría a esta clase para cambiarla.

Si quisiera venir a esta clase cuando quiera cambiar las reglas para validar a una Persona, no quiero ir a la misma clase para cambiar las reglas para validar una Orden, ni quiero venir aquí para cambiar dónde persistir una persona.

Dicho esto, si apuntas a eso, rara vez encontrarás clases de más de 200 líneas. Sucederán, por razones válidas, pero serán raros. Entonces, si está buscando una métrica de bandera roja, entonces no es un mal lugar para comenzar; pero que sea una guía, no una regla.

pdr
fuente
200 parece correcto como una suposición muy aproximada. Como tú dices, no es lo que te preocupa primero.
Steve
Lo otro sobre Java es que, al contar los LOC, ignoraría los captadores / establecedores.
MrFox
1
@ MrFox: No estoy de acuerdo. Si su clase tiene suficientes captadores y establecedores para sesgar los datos LOC, eso cuenta en contra en el "¿esta clase está haciendo demasiado?" pregunta. Sin embargo, como compromiso, estaría dispuesto a obtener / establecer NetBean a menos de 1 línea / línea por respeto a la placa de caldera excesiva que tienen tales métodos.
Brian
23

Lo siento, pero estoy muy sorprendido de que muchas respuestas indiquen que "realmente no importa". Importa MUCHO cuántas líneas hay en una clase. ¿Por qué? Considere estos principios al escribir un buen código Java ...

  • Testabilidad
  • Cohesión
  • Acoplamiento
  • Comprensibilidad

Las clases con muchas líneas probablemente violarán todos esos principios.

Para aquellos que lo han declarado "realmente no importa" ... ¿qué tan divertido ha sido para ti intentar entender una clase que tiene más de 5000 líneas? ¿O para modificarlo? Si dices que es divertido, tienes una extraña afinidad con el dolor ...

Yo diría que cualquier clase que tenga más de 1000 líneas debería al menos ser cuestionada sobre cómo pueden estar violando los principios anteriores y posiblemente analizados en varias clases "fuera de tiro".

Mis comentarios se basan en leer y estudiar autores como Martin Fowler, Joshua Bloch y Misko Hevery. Son excelentes recursos para consultar para escribir un buen código Java.

Hazle un favor al siguiente tipo (que podrías ser tú en un par de años) y esfuérzate por escribir clases que tengan menos líneas en lugar de más.

Zack Macomber
fuente
Creo que todos están de acuerdo en que 5000+ generalmente no es una buena señal (sin contar las clases anidadas), pero sienten que es más un efecto secundario o algo más que el problema real. Por supuesto, algunas personas son demasiado detalladas y usan un número excesivo de líneas solo para declarar e inicializar variables y demás, y necesitan detener eso. Eso lo hace menos legible. Pero si se relaciona con la estructura de clases, el problema no es el LOC en sí mismo; Es el hecho de que alguien simplemente no está rompiendo las cosas muy bien, y el LOC es un efecto secundario de eso.
Panzercrisis
2
El punto es que una clase debe tener una alta cohesión y una responsabilidad clara, lo que significa que las clases generalmente no crecen tanto. Pero si una clase está bien diseñada pero aún tiene más de 5000 líneas de código, no ayuda a nadie dividirla en varias clases más pequeñas estrechamente acopladas.
JacquesB
12

Depende de la complejidad, no del número de líneas. He escrito grandes rutinas tontas que fueron fáciles de entender y que hicieron precisamente una cosa y lo hicieron bien, pero continuaron durante cientos de líneas. He escrito funciones bastante cortas que eran difíciles de entender (y depurar).

Otra cosa que podría observar es la cantidad de funciones públicas en una clase. Eso también puede ser una señal de advertencia.

No tengo buenos recuentos disponibles, pero sugeriría buscar un código decente que haga cosas útiles en su tienda y basarlo en eso. Ciertamente, debe mirar las clases más largas y las API más grandes.

David Thornley
fuente
77
+1: No midas cosas tontas como líneas. La complejidad ciclomática y el recuento de características (número de métodos) tienen más sentido para las líneas.
S.Lott
2
si y no. Un número excesivo de líneas suele ser un síntoma de un mal diseño y, por lo tanto, una señal de alerta de que la clase probablemente necesita refactorizarse.
Jwenting
1
@jwenting Sí, a eso me refería. ¡Sé muchas líneas! = Necesita ser refactorizado, pero casi todas las clases con las que estoy trabajando que realmente necesitan ser refactorizadas debido al diseño deficiente tienen muchas líneas.
Michael McGowan
5

Hay demasiadas líneas de código si la clase está haciendo demasiadas cosas diferentes. Esencialmente, si sigue el principio de Responsabilidad Individual para las clases, hay un límite en cuanto al tamaño de la clase crecerá.

En cuanto a las limitaciones físicas que puede tener (fuente: formato de archivo de clase Java5 ):

  • 65.536 constantes, interfaces aplicadas, campos, métodos y atributos, cada uno. NOTA: se quedará sin espacio constante antes de quedarse sin ninguno de los otros elementos. NOTA 2: los atributos son construcciones de archivos de clase, que no deben confundirse con los marcadores '@Attribute' (es decir, la información de depuración y el código de bytes se almacenan como atributos separados para un método).
  • Cada método puede tener 4 GB (32 bits) de código de bytes generado. NOTA: Las versiones de Java anteriores a la 1.5 solo podían tener 64 KB (16 bits) de código de bytes generado para cada método.

En resumen, el archivo de clase puede ser mucho más grande de lo que cualquiera consideraría útil. Si se apega al principio de responsabilidad única, sus archivos de clase serán del tamaño correcto.

Berin Loritsch
fuente
1
+1 por responsabilidad única :) @Berin ¿implementa esto estrictamente en su software?
Aditya P
Si. El truco es dividir las responsabilidades de una manera que tenga sentido.
Berin Loritsch
ah, el viejo límite de 64 KB. Buena prueba de Lithmus para ver si sus JSP son demasiado complejos, ya que se traducen a un solo método con muchas declaraciones println para todos sus html estáticos :)
jwenting
A partir de Java 5, lo han aumentado a 4 GB. No te preocupes allí ahora.
Berin Loritsch
5

La respuesta correcta es 42. Es broma.
En realidad, las líneas máximas recomendadas por clase son 2000 líneas.

Las "Convenciones de código Java" desde 1999 lo han dicho de esta manera: los
archivos de más de 2000 líneas son engorrosos y deben evitarse.

Después de seguir las convenciones de Sun / Oracle Coding desde que se inventó Java, he encontrado que esta regla práctica en las líneas por clase es razonable. El 99% de su código Java debe cumplir ... Y si supera el 2000, simplemente coloque un TODO en la parte superior diciendo que la clase necesita trabajo.

Lo peor es el caso opuesto cuando los programadores crean demasiadas clases pequeñas con casi ninguna funcionalidad real en cada clase. Ignorando el consejo de "Favorecer la composición", los programadores crean cientos de clases heredadas que crean modelos de objetos complicados que son mucho peores que el problema de la clase grande (que al menos generalmente mantienen la funcionalidad con un nombre de clase relevante).

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

usuario1865223
fuente
En realidad, la mayoría de ellos son comentarios @LluisMartinez
Xtreme Biker
Estoy totalmente en desacuerdo con el 2000 . Una clase no debe tener más de 200 líneas excluyendo comentarios.
Nikolas
4

Código limpio:

¡Las clases deben ser pequeñas!

La primera regla de las clases es que deberían ser pequeñas. La segunda regla de clases es que deberían ser más pequeñas que eso. No, no vamos a repetir exactamente el mismo texto del capítulo Funciones. Pero como con las funciones, más pequeño es la regla principal cuando se trata de diseñar clases. Al igual que con las funciones, nuestra pregunta inmediata es siempre "¿Qué tan pequeño?"

** Con funciones medimos el tamaño contando líneas físicas. Con las clases usamos una medida diferente. Contamos las responsabilidades. **

El nombre de una clase debe describir qué responsabilidades cumple. De hecho, nombrar es probablemente la primera forma de ayudar a determinar el tamaño de la clase. Si no podemos derivar un nombre conciso para una clase, entonces es probable que sea demasiado grande. Cuanto más ambiguo sea el nombre de la clase, más probable es que tenga demasiadas responsabilidades. Por ejemplo, los nombres de clase que incluyen palabras de comadreja como Procesador o Gerente o Super a menudo insinúan una desafortunada agregación de responsabilidades.

Entonces:

  • Solo asegúrese de que sus métodos solo hagan una cosa.
  • Luego, asegúrese de que la clase no tenga demasiadas responsabilidades.

Terminarás con una clase de un tamaño manejable.

Tulains Córdova
fuente
si Clean Codeademás de su respuesta se refiere al libro de Robert C. Martin (¡lo que hace!), entonces tengo que decirle y lo tengo en común; ese libro es lo que me llevó a esta pregunta. Creo que esta respuesta lo dice todo
Sнаđошƒаӽ
2

El número de líneas es una métrica bastante pobre para la calidad de la clase. Para mí, me gusta mirar (como otros han mencionado) los métodos públicos, así como cualquier propiedad expuesta públicamente (supongo que los captadores / establecedores públicos en Java). Si tuviera que sacar un número del aire para cuando pueda llamar mi atención, diría que hay más de 10 de cada uno. Realmente, si se trata de más de 5 propiedades o métodos, echaré un vistazo y a menudo encontraré formas de refactorizar, pero cualquier cosa por encima de 10 suele ser una señal de advertencia de que es bastante probable que algo esté mal expuesto.

Es otra conversación por completo, pero los métodos y campos privados son menos olor para mí, por lo que si están contribuyendo mucho a la cantidad de líneas, entonces podría no estar tan preocupado. Por lo menos, muestra que probablemente no haya algún controlador de Dios manipulando el objeto desde lejos, lo cual es un problema de diseño bastante problemático.

Morgan Herlocker
fuente
2

Intenta usar una mejor métrica.

Un ejemplo es la métrica ABC . Es más una medida de cuánto trabajo está haciendo el código que cuánto código hay.

sylvanaar
fuente
1

Cualquier línea que se encuentre dentro del dominio del problema de su clase escrita fuera de la clase es una línea muy poca y una demasiada en la clase donde vive. Piensa en una clase como un tema. Tienes que taparlo. Lo más concisa posible es ideal, pero si toma 500 líneas, toma 500 líneas. Si 100 de esas líneas cubren otro tema, pertenecen a otro lugar. Irrumpir en subdominios más pequeños dentro de la clase como clases interiores tiene sentido, pero solo definiría a los que están fuera de la clase si lo hubieran usado en otro lugar.

Erik Reppen
fuente