¿Existe un número óptimo de líneas de código por función? [cerrado]

18

Las funciones no solo se usan para minimizar la duplicación de código, también se usan para dividir una función larga en otras más pequeñas para aumentar la legibilidad, así como hacer que el código se auto comente. Sin embargo, esta ganancia no es directamente inversamente proporcional al número de LOC por función o método; de lo contrario tendríamos toneladas de funciones, todas las cuales solo contienen una o dos líneas de código.

Esto me lleva a preguntarme: ¿existe un número óptimo de LOC por función? Si es así, ¿qué es y se desvía entre idiomas?

gablin
fuente
66
Vea Code Complete Vol 2 por Mitch McConnell Capítulo 7 Sección 4 para un buen momento.
Peter Turner
2
@ Peter - Creo que te refieres a "Steve McConnell"
JohnFx
Sí, curioso, escribiría eso mientras miraba el libro ... Wasnt Mitch McConnell Pres. ¿El jefe de gabinete de Bush?
Peter Turner,
3
El número casi seguro varía según el idioma: me sorprendería ver una cláusula Prolog de 6 líneas, a la vez que estoy perfectamente bien con un método Delphi de 20 líneas. Mi respuesta a continuación es para Smalltalk, que utiliza el entorno para fomentar métodos cortos.
Frank Shearar
1
@ Peter Turner: Hm ... S1 a S15 e I1 a I11. Parece que está confundiendo variables temporales con registros. ^^
gablin

Respuestas:

33

En lugar del número de líneas, el criterio que usaría es que cada función debe hacer solo una cosa y hacerlo bien.

grokus
fuente
Sí, si tenemos una unidad de trabajo, no quiero tener que moverme entre 50 funciones para entender lo que está sucediendo. Si desglosa sus funciones de manera adecuada utilizando esta métrica, deberían ser, naturalmente, de un tamaño razonable.
ChaosPandion
2
@ChaosPandion: pero su unidad de trabajo puede expresarse probablemente como una secuencia de pasos más elementales. Si está revisando la función, revisará la secuencia de pasos, no el código de cada paso.
Wizard79
2
@Lorenzo: si ese es el caso, cada paso se convierte en la unidad de trabajo. La función principal se convierte en una descripción general de alto nivel de las unidades de trabajo.
ChaosPandion
1
Sí, esto es muy cierto. Hm, permítanme reformular la pregunta entonces: ¿Hay un número óptimo de LOC para funciones que solo hace una cosa y lo hace bien?
gablin
@gablin, difícil de decir y también los LOC dependen del idioma, pero si se adhiere a este principio, generalmente termina dentro de un rango razonable, digamos 1 ~ 50.
grokus
21

Una vieja regla general es que una función debe ser completamente visible en la pantalla, sin necesidad de desplazarse.

La idea básica es que, si no puede ver toda la función a la vez, la función es demasiado compleja y debe dividirla en partes más básicas.

Si bien esta regla es muy práctica y útil, la regla formal es que debe mantener solo un paso lógico en una función. Una función solo hace un trabajo elemental, si puede dividir el trabajo en más piezas elementales, la función debe dividirse.

Wizard79
fuente
21
Esta métrica se vuelve progresivamente más inútil a medida que aumenta el tamaño / resolución promedio del monitor.
Adam Lear
2
Nuestro profesor de programación acaba de decir este ejemplo la otra noche :)
cdnicoll
2
@ Anna: bueno, mi monitor es de alta resolución, pero también ha aumentado el número de barras de herramientas / paletas / panel. Y luego, ¡ahora puedo usar una fuente de paso de 14 pt! :)
Wizard79
44
El tamaño de 24 x 80 de un terminal no tiende a cambiar.
alternativa
1
sin sentido, el objetivo de la regla es "puedes verlo todo sin desplazarte". Con un monitor grande puede tener más en su función sin violar esta regla, no significa que a los monitores grandes solo se les permita ver funciones pequeñas (aunque con todas las barras de herramientas y ventanas de propiedades que tiene su IDE, esto probablemente todavía sea cierto: - ))
gbjbaanb
15

No hay ninguno.

Las pantallas se hacen más grandes, los tamaños de fuente son más pequeños. Las reglas generales no funcionan tan bien cuando las personas tienen pulgares de diferentes tamaños.

Sé conciso. Si su función hace varias cosas, probablemente sea una buena idea dividirla en otras más pequeñas.

Josh K
fuente
Lo menos que puedes hacer es decirme por qué crees que mi respuesta no es útil.
Josh K
77
Creo que alguien se ofendió por el uso de la etiqueta h1 .
ChaosPandion
@Chaos: Esa es la respuesta esencial.
Josh K
66
Tal vez fui un poco demasiado sutil, pero mi intención era implicar que no hay una razón válida para rechazar su respuesta. Quien hizo el acto tenía alguna razón personal al azar para hacerlo. Puede que simplemente piensen que Josh es un nombre horrible.
ChaosPandion
6

Smalltalk tiene una forma ligeramente inusual de reducir el tamaño de los métodos. Cuando escribe código, lo escribe en un widget llamado Navegador. Un navegador tiene dos partes principales, divididas horizontalmente. Tu código va en la mitad inferior.

Por defecto, un navegador no es muy grande. Puede colocar 5 o 6 líneas antes de que deba comenzar a desplazarse. El desplazamiento, por supuesto, es un poco irritante.

Entonces, en Smalltalk, el entorno "lo alienta" a escribir métodos cortos, de como máximo alrededor de 6 líneas de longitud. (Eso suele ser suficiente; Smalltalk es un lenguaje bastante conciso).

Frank Shearar
fuente
2

El número ideal de líneas de código en un método es variable. Básicamente, solo desea escribir el código suficiente para hacer lo que debe hacerse dentro del contexto de la definición de la función. Pienso en esto como una especie de Principio de responsabilidad única, solo aplicado a un método en lugar de una clase.

Cuando un método tiene mucha lógica y varios pasos para completar, entonces tiene sentido dividir el método en varios pasos discretos. Cada uno de estos pasos se extraería en nuevos métodos según sea necesario.

"De lo contrario, tendríamos toneladas de funciones, todas las cuales solo contienen una o dos líneas de código".

Cuanto menos haga cada método, más fácil será definirlo y más sencillo de comprender y gestionar. No hay nada de malo en tener cientos de métodos si los necesita. Además, de acuerdo con el SRP que mencioné anteriormente, se hace más fácil extraer nuevas clases cuando los métodos se han separado en piezas más pequeñas y manejables.

S.Robins
fuente
1

La respuesta es, por supuesto, 42 .

Importante tener en cuenta: ninguna función puede violar el SRP , o debe enfrentarse a la inquisición española .

Algunos consejos sobre cómo reducir la cantidad de líneas:

  • ¿Hay comentarios que marcan secciones individuales? Esas secciones deberían ser funciones.
  • ¿Hay cadenas if-else o declaraciones de cambio fuera de una fábrica / constructor? Su diseño puede necesitar algunos patrones de diseño mejores para ayudarlo a dividir las responsabilidades.
  • ¿Sus funciones son fáciles de probar? Haga que sus funciones sean fáciles de probar, se desmoronarán.
  • ¿Es complejo y simplemente no hay tierra en profundidad (1000 monstruos de línea)? Haz refactorización de chatarra, es decir, refactoriza y no la guardes con la esperanza de educarte sobre las responsabilidades de los códigos.
Johannes
fuente
1
Nᴏʙᴏᴅʏ espera el español ... ah, cabrón, llego un poco tarde aquí.
Leftaroundabout
0

Aquí hay algunas pistas:

  • Si tiene problemas para escribir el comentario explicando el propósito y el uso de la función, es demasiado largo.

  • Si está tentado a escribir un comentario explicando la actividad de una sección de código en la función, entonces la función es demasiado larga.

  • Si está pegando código de otra función, ambos son demasiado largos (extraiga ese código como una función separada).

  • Si necesita una convención de codificación para separar los miembros de datos de clase de las variables locales, entonces la función es demasiado larga y la clase tiene demasiados miembros.

  • Si necesita tomar notas mientras lee una función, es demasiado larga.

Tener 'toneladas' de funciones, cada una de una o dos líneas de largo, no es necesariamente algo malo. Descubrí que esas pequeñas funciones se reutilizaban mucho más de lo que inicialmente esperaba.

Kevin Cline
fuente