2008-10-30 5 views
28

¿Es mejor escribir muchos métodos pequeños (o funciones), o simplemente escribir la lógica/código de esos pequeños procesos directamente en el lugar donde habría llamado el método pequeño? ¿Qué hay de romper el código en una función pequeña, incluso si por el momento solo se llama desde un punto?Mejores prácticas: ¿muchas funciones/métodos pequeños, o funciones más grandes con componentes de proceso lógicos en línea?

Si la elección depende de algunos criterios, cuáles son; ¿Cómo debería un programador hacer un buen juicio?

Espero que la respuesta se pueda aplicar generalmente en muchos idiomas, pero si es necesario, las respuestas dadas pueden ser específicas para un idioma o idiomas. En particular, estoy pensando en SQL (funciones, reglas y procedimientos almacenados), Perl, PHP, Javascript y Ruby.

+0

cosas división ayuda a la legibilidad del código. if (Convert.ToBoolean (fila ["IsActive"])) es menos legible que "if (obj.IsActive)". :) –

+0

Hm. Pregunta SOF relacionada: http://stackoverflow.com/questions/20981/how-many-lines-of-code-is-too-many – Pistos

+0

Personalmente no me gusta cuando el código tiene muchas funciones muy pequeñas (1-3 líneas) que solo se llaman desde un solo lugar (cosas como 'int foo() {return do_foo();} int do_foo() {/ * código real * /}' es el peor, IMO) Luego, para entender una función útil real compuesta de estas piezas, tengo que perseguir cada subfunción y es a) fácil de perder en b) fácil de perder de vista las posibles optimizaciones. Diría que si encaja perfectamente en una pantalla y no hay posibilidad de volver a usarla, no la dividas. – PSkocik

Respuesta

30

Siempre rompo los métodos largos en trozos lógicos y trato de hacer métodos más pequeños de ellos. Yo no normalmente convertir algunas líneas en un método separado hasta que lo necesito en dos lugares diferentes, pero a veces lo hago para ayudar a la legibilidad, o si quiero probarlo en forma aislada.

Fowler's Refactoring es todo sobre este tema, y ​​lo recomiendo encarecidamente.

Aquí hay una práctica regla general que utilizo de Refactoring. Si una sección de código tiene un comentario que podría volver a escribir en un nombre de método, sáquelo y conviértalo en un método.

+0

no estoy de acuerdo más! (tu respuesta me salvó una vez) – iTSrAVIE

8

Como siempre puedes decir: depende. Es más una cuestión de nombrar y definir la tarea de un método. Cada método debe hacer una tarea (no más) bien definida y debe hacerlas por completo. El nombre del método debe indicar la tarea. Si su método se llama DoAandB(), puede ser mejor tener métodos separados DoA() y DoB(). Si necesita métodos como setupTask, executeTask, FinishTask, puede ser útil combinarlos.

Algunos puntos que indican, que una combinación de diferentes métodos pueden ser útiles:

  • un método no puede ser utilizado solo, sin el uso de otros métodos.
  • Debe tener cuidado de llamar a algunos métodos dependientes en el orden correcto.

Algunos puntos que indican que un splitup del método podría ser útil:

  • Algunas líneas del método de trabajo independiente existentes tienen claro.
  • Pruebas unitarias del método grande se vuelven problemáticas. Si las pruebas son más fáciles de escribir para métodos independientes, entonces divida el método grande.

Como una explicación para el argumento de prueba de unidad: escribí un método, que hizo algunas cosas, incluyendo IO. La parte IO fue muy difícil de probar, así que lo pensé. Llegué a la conclusión de que mi método hizo 5 pasos lógicos e independientes, y solo uno de ellos involucró el IO. Así que dividí mi método en 5 más pequeños, cuatro de ellos fueron fáciles de probar.

1

Algunas reglas de oro:

  • Las funciones no debe ser más largo de lo que se puede visualizar en la pantalla
  • funciones de rotura en los más pequeños si se hace que el código sea más legible.
+0

Tu primer comentario funcionaría en la mayoría de los casos, pero tengo una pantalla de 30 pulgadas. Además, vi a un compañero de trabajo con su monitor girado verticalmente. Entonces, creo que se necesita una nueva regla empírica. – kevindaub

0

Personalmente, me inclino significativamente en la dirección de preferir más métodos más pequeños, pero no al punto de apuntar religiosamente a un recuento máximo de líneas. Mi criterio principal u objetivo es mantener mi código SECO. En el momento en que tengo un bloque de código que está duplicado (ya sea en espíritu o en realidad por el texto), incluso si tiene 2 o 4 líneas, RASGO ese código en un método diferente. Algunas veces lo haré con anticipación si creo que hay una buena posibilidad de que se vuelva a usar en el futuro.

Por otro lado, también he escuchado argumentar que si su método de separación es demasiado pequeño, en el contexto de un equipo de desarrolladores, es probable que un compañero no conozca su método y escriba en línea, o escriba su propio pequeño método que hace lo mismo. Esta es sin duda una mala situación.

Algunos también intentan argumentar que es más legible para mantener las cosas en línea, por lo que un lector puede leer de arriba hacia abajo, en lugar de tener que saltar alrededor de las definiciones de métodos, posiblemente en varios archivos. Personalmente, creo que la existencia de un seguimiento de pila hace que esto no sea un gran problema.

1

Cuanto mayor sea el método, más difícil de probar y mantener. Encuentro que es mucho más fácil entender cómo funciona un proceso grande cuando se divide en pasos atómicos. Además, hacer esto es un gran primer paso para hacer que tus clases sean extensibles. Puede marcar esos pasos individuales como virtuales (para herencia) o moverlos a otros objetos (composición), facilitando la personalización del comportamiento de la aplicación.

1

Hago que cada función haga una cosa, y una sola cosa, y trato de no anidar demasiados niveles de lógica. Una vez que comience a dividir su código en bien llamadas funciones, se vuelve mucho más fácil de leer y prácticamente autodocumentado.

11

El tamaño del método está directamente relacionado con su cyclomatic complexity.

Las principales ventajas para mantener el tamaño del método pequeñas (que significa dividir un gran método en varios métodos pequeñas) son:

  • mejor prueba de la unidad (debido a la baja complejidad ciclomática)
  • mejor depuración debido a un rastro de pila más explícito (en lugar de un error dentro de un método gigante)
1

Me parece que tener muchos métodos pequeños hace que el código sea más fácil de leer, mantener y depurar.

Cuando estoy leyendo una unidad que implementa cierta lógica comercial, puedo seguir mejor el flujo si veo una serie de llamadas a métodos que describen el proceso. Si me importa cómo se implementa el método, puedo buscar el código.

Parece más trabajo pero, en última instancia, ahorra tiempo.

Creo que hay un arte para saber qué encapsular. Todos tienen una ligera diferencia de opinión. Si pudiera expresarlo en palabras, diría que cada método debería hacer una cosa que pueda describirse como una tarea completa.

1

Normalmente prefiero dividir funciones en funciones más pequeñas que realizan una sola tarea atómica, pero solo si esa función es lo suficientemente compleja como para evitarla.

De esta manera, no termino con funciones múltiples para tareas simples, y las funciones que extraigo normalmente se pueden usar en otros lugares, ya que no intentan lograr demasiado. Esto también ayuda a la prueba unitaria ya que cada función (como una acción lógica y atómica) se puede probar individualmente.

5

Métodos pequeños todo el tiempo.

Ellos son autodocumentado (er, si bien el nombre)

Rompen el problema en partes más manejables - usted es KeepingItSimple.

Puede utilizar las técnicas de OO para un comportamiento de conexión más fácil (y obviamente). El método grande es, por definición, más procesal y, por lo tanto, menos flexible.

Son unidades de prueba de la unidad. Este es el asesino, usted simplemente no puede unidad de prueba algún método enorme que realiza una carga de tareas

+1

+1 por simplicidad y facilidad de prueba. Agrega reutilizable y tienes un trabajo. :-) –

2

Algo que aprendí de El Código Libro completo: métodos

  • escritura/funciones para que se implemente una pedazo (o unidad o tarea) de la lógica. Si eso requiere el desglose en tareas secundarias, escriba un método/función independiente para ellos y llámelos.
  • Si encuentro que el método/función nombre está recibiendo mucho tiempo, entonces trato de examinar el método para verlo puede dividirse en dos métodos.

Esperanza esto ayuda

Cuestiones relacionadas