¿Cuántos parámetros son demasiados? [cerrado]


Las rutinas pueden tener parámetros, eso no es noticia. Puede definir tantos parámetros como necesite, pero demasiados de ellos harán que su rutina sea difícil de entender y mantener.

Por supuesto, podría usar una variable estructurada como solución: poner todas esas variables en una sola estructura y pasarla a la rutina. De hecho, el uso de estructuras para simplificar las listas de parámetros es una de las técnicas descritas por Steve McConnell en Code Complete. Pero como él dice:

Los programadores cuidadosos evitan agrupar datos más de lo que es lógicamente necesario.

Así que si tu rutina tiene demasiados parámetros o usas una estructura para disfrazar una gran lista de parámetros, probablemente estés haciendo algo mal. Es decir, no estás manteniendo el acoplamiento suelto.

Mi pregunta es, ¿cuándo puedo considerar una lista de parámetros demasiado grande? creo que más de 5 parámetros, son demasiados. ¿Qué opinas?

Author: Auron, 2008-10-06

30 answers

¿Cuándo se considera algo tan obsceno como para ser algo que puede ser regulado a pesar de la garantía de la 1ra Enmienda a la libertad de expresión? Según el juez Potter Stewart, " Lo sé cuando lo veo."Lo mismo ocurre aquí.

Odio hacer reglas duras y rápidas como esta porque la respuesta cambia no solo dependiendo del tamaño y el alcance de su proyecto, sino que creo que cambia incluso hasta el nivel del módulo. Dependiendo de lo que su método está haciendo, o lo que se supone que la clase representar, es muy posible que 2 argumentos es demasiado y es un síntoma de demasiado acoplamiento.

Sugeriría que al hacer la pregunta en primer lugar, y calificar su pregunta tanto como lo hizo, que realmente sabe todo esto. La mejor solución aquí no es confiar en un número duro y rápido, sino buscar revisiones de diseño y revisiones de código entre sus compañeros para identificar áreas donde tiene baja cohesión y acoplamiento estrecho.

Nunca tengas miedo de mostrar sus colegas su trabajo. Si tienes miedo, esa es probablemente la señal más grande de que algo está mal con tu código, y que ya lo sabes.

 162
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 21:20:32

Una función solo puede tener demasiados parámetros si algunos de los parámetros son redundantes. Si se utilizan todos los parámetros, la función debe tener el número correcto de parámetros. Tome esta función de uso frecuente:

HWND CreateWindowEx
(
  DWORD dwExStyle,
  LPCTSTR lpClassName,
  LPCTSTR lpWindowName,
  DWORD dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  HWND hWndParent,
  HMENU hMenu,
  HINSTANCE hInstance,
  LPVOID lpParam
);

Son 12 parámetros (9 si agrupas la x,y,w y h como un rectángulo) y también están los parámetros derivados del nombre de la clase. ¿Cómo reducirías esto? ¿Querrías reducir el número más al punto?

No deje que el número de parámetros te molesta, solo asegúrate de que sea lógico y bien documentado y deja que intellisense* ayudarte.

* Otros asistentes de codificación están disponibles!

 123
Author: Skizz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-02 09:43:32

En Clean Code, Robert C. Martin dedicó cuatro páginas al tema. Aquí está la esencia:

El número ideal de argumentos para una la función es cero (niladic). Luego viene uno (monádico), seguido de cerca por dos (dyadic). Tres argumentos (triádico) debe evitarse siempre que sea posible. Mas que tres (poliádico) requiere muy justificación especial -- y luego no debería usarse de todos modos.

 106
Author: Patrick McElhaney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-24 22:00:21

Algunos códigos con los que he trabajado en el pasado usaban variables globales solo para evitar pasar demasiados parámetros.

Por Favor, no hagas eso!

(Usualmente.)

 79
Author: Jeffrey L Whitledge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:28:52

Si comienza a tener que contar mentalmente los parámetros en la firma y hacerlos coincidir con la llamada, entonces es hora de refactorizar!

 38
Author: Rob Walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:19:35

Muchas gracias por todas sus respuestas:

  • Fue un poco sorprendente encontrar personas que también piensan (como yo) que 5 parámetros es un buen límite para la cordura del código.

  • Generalmente, las personas tienden a estar de acuerdo en que un límite entre 3 y 4 es una buena regla general. Esto es razonable ya que la gente suele pasar un mal rato contando más de 4 cosas.

  • As Milan puntos , en promedio la gente puede guardar más o menos 7 cosas en su cabeza a la vez. Pero creo que no puedes olvidar que, cuando estás diseñando/manteniendo/estudiando una rutina, tienes que tener en cuenta más cosas que solo los parámetros.

  • Algunas personas consideran que una rutina debe tener tantos argumentos como necesita. Estoy de acuerdo, pero solo para unos pocos casos específicos (llamadas a las API del sistema operativo, rutinas donde la optimización es importante, etc.). Sugiero ocultar la complejidad de estas rutinas agregando una capa de abstracción justo por encima de estas llamadas siempre que sea posible.

  • Nick tiene algunos pensamientos interesantes en este. Si no quieres leer sus comentarios, te resumo: en pocas palabras, depende :

    Odio hacer reglas duras y rápidas como esta porque la respuesta cambia no solo dependiendo del tamaño y el alcance de su proyecto, sino que creo que cambia incluso hasta el nivel del módulo. Dependiendo de lo que su método está haciendo, o lo que la clase se supone que representa, es muy posible que 2 argumentos es demasiado y es un síntoma de demasiado acoplamiento.

    La moraleja aquí es no tener miedo de mostrar su código a sus compañeros, discutir con ellos y tratar de "identificar las áreas donde tiene baja cohesión y acoplamiento apretado".

  • Finalmente, creo que wnoise está de acuerdo con Nick, y concluye su contribución satírica con esta visión poética (ver comentarios a continuación) del arte de programación:

    La programación no es ingeniería. La organización del código es un arte porque depende de factores humanos, que dependen demasiado del contexto para cualquier regla dura.

 31
Author: Auron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:03

Esta respuesta asume un lenguaje OO. Si no está usando una skip omita esta respuesta (en otras palabras, esta no es una respuesta completamente independiente del lenguaje.

Si está pasando más de 3 parámetros (especialmente tipos/objetos intrínsecos), no es que sean "demasiados", sino que puede estar perdiendo la oportunidad de crear un nuevo objeto.

Busque grupos de parámetros que se pasan a más de un método even incluso un grupo pasado a dos métodos casi garantiza que debe tener un nuevo objeto.

Luego refactoriza la funcionalidad en tu nuevo objeto y no creerías cuánto ayuda tanto a tu código como a tu comprensión de la programación OO.

 16
Author: Bill K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:43:55

Parece que hay otras consideraciones además del mero número, aquí hay algunas que vienen a la mente:

  1. Relación lógica con el propósito principal de la función vs. configuración única

  2. Si son solo indicadores de entorno, la agrupación puede ser muy útil

 13
Author: John Mulder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:22:34

Uno de los conocidos epigramas de programación de Alan Perlis (relatado en ACM SIGPLAN Notices 17(9), Septiembre de 1982) afirma que "Si tienes un procedimiento con 10 parámetros, probablemente te perdiste algunos."

 12
Author: Peter S. Housel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 17:59:40

Según Steve McConnell en Code Complete , debes

Limitar el número de rutinas parámetros a aproximadamente siete

 11
Author: Paul Reiners,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-25 23:48:44

Para mí , cuando la lista cruza una línea en mi IDE, entonces es un parámetro demasiado. Quiero ver todos los parámetros en una línea sin romper el contacto visual. Pero esa es mi preferencia personal.

 9
Author: Learning,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:17:46

Generalmente estoy de acuerdo con 5, sin embargo, si hay una situación en la que necesito más y es la forma más clara de resolver el problema, entonces usaría más.

 9
Author: Inisheer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:18:13

Siete cosas en la memoria a corto plazo?

  1. Nombre de la función
  2. Valor de retorno de la función
  3. Propósito de la función
  4. Parámetro 1
  5. Parámetro 2
  6. Parámetro 3
  7. Parámetro 4
 8
Author: Mike Clark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-18 03:57:59

En Los peores 5 Fragmentos de código, marque el segundo, "Es este un constructor". Tiene como más de 37 ⋅ 4 ≈ 150 parámetros:

Aquí un programador escribió este constructor [... S] ome de ustedes puede pensar que sí es un gran constructor, pero utilizó eclipse herramientas automáticas de generación de código[.] NOO, en este constructor había un pequeño error que descubrí, que me hizo concluir que este constructor fue escrito a mano. (por cierto, esto es solo la parte superior del constructor, no es completo).

constructor con más de 150 parámetros

 7
Author: medopal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-25 23:16:38

Uno más de lo necesario. No quiero ser simplista, pero hay algunas funciones que necesariamente necesitan bastantes opciones. Por ejemplo:

void *
mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset);

Hay 6 argumentos, y cada uno de ellos es esencial. Además, no hay un vínculo común entre ellos que justifique agruparlos. Tal vez podrías definir "struct mmapargs", pero eso sería peor.

 6
Author: Kirk Strauser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:35:44

De acuerdo con Las Mejores Prácticas de Perl, 3 está bien, 4 es demasiado. Es solo una guía, pero en nuestra tienda es a lo que tratamos de atenernos.

 5
Author: Adam Bellaire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:18:42

Yo mismo dibujaría el límite para las funciones públicas en 5 parámetros.

En mi humilde opinión, las listas largas de parámetros solo son aceptables en funciones auxiliares privadas/locales que solo están destinadas a ser llamadas desde unos pocos lugares específicos en el código. En esos casos, es posible que tenga que pasar una gran cantidad de información de estado, pero la legibilidad no es una gran preocupación ya que solo usted (o alguien que mantendrá su código y debe entender los fundamentos de su módulo) tiene que preocuparse por llamar a eso función.

 5
Author: Kip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:24:29

Una pregunta relacionada que debe considerar es cómo cohesiva es la rutina. Un gran número de parámetros puede ser un olor que te está diciendo que la rutina en sí está tratando de hacer demasiado y por lo tanto su cohesión es sospechosa. Estoy de acuerdo en que un número duro y rápido de parámetros es probablemente imposible, pero supongo que una rutina de alta cohesión implicaría un número bajo de parámetros.

 5
Author: Onorio Catenacci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-28 13:42:38

97 suena justo.

Menos y se pierde flexibilidad.

 5
Author: Johan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:02

Me detengo en tres parámetros como regla general. Más y es hora de pasar una matriz de parámetros o un objeto de configuración en su lugar, que también permite que se agreguen parámetros futuros sin cambiar la API.

 4
Author: Eran Galperin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:24:28

Una restricción de longitud en una lista de parámetros es solo una restricción más. Y la restricción significa violencia aplicada. Suena divertido, pero puede ser no violento incluso cuando se programa. Deja que el código dicte las reglas. Es obvio que si tiene muchos parámetros, el cuerpo del método función/clase será lo suficientemente grande como para hacer uso de ellos. Y los grandes fragmentos de código generalmente se pueden refactorizar y dividir en trozos más pequeños. Así que obtienes solución contra tener muchos parámetros como bono gratis, ya que se dividen entre las piezas de código refactorizadas más pequeñas.

 4
Author: Anonymous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:34:53

Una cosa que señalaría desde una perspectiva de rendimiento es que dependiendo de cómo pase parámetros a un método, pasar muchos parámetros por valor ralentizará el programa porque cada parámetro tiene que ser copiado y luego colocado en la pila.

Usar una sola clase para abarcar todos los parámetros funcionaría mejor porque un solo parámetro pasado por referencia sería elegante, más limpio y más rápido.

 4
Author: Dominic Zukiewicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-26 07:46:48

Según mí, podría haber casos en los que excederá 4 o algún número fijo. Cosas a lookout podría ser

  1. Su Método está haciendo demasiado y necesita refactorizar.
  2. Es posible que desee considerar el uso de una colección o alguna estructura de datos.
  3. Repiense el diseño de su clase, tal vez algunas cosas no necesitan pasarse.

Desde un ángulo de facilidad de uso o facilidad de lectura de código, creo que cuando necesita un poco de "ajuste de línea" su firma de método, eso debería hacer que te detengas y pienses, a menos que te sientas impotente y todos los esfuerzos de hacer que la firma sea más pequeña no lleven a ningún resultado. Algunas bibliotecas muy buenas en el pasado y el presente utilizan más de 4-5 cochecitos.

 3
Author: Perpetualcoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-25 23:41:07

Mi regla general es que necesito ser capaz de recordar los parámetros el tiempo suficiente para mirar una llamada y decir lo que hace. Así que si no puedo mirar el método y luego voltear a una llamada de un método y recordar qué parámetro hace lo que entonces hay demasiados.

Para mí eso equivale a aproximadamente 5, pero no soy tan brillante. Su kilometraje puede variar.

Puede crear un objeto con propiedades para mantener los parámetros y pasar en si excede cualquier límite establecido. Ver El libro de Martin Fowler Refactorización y el capítulo sobre cómo simplificar las llamadas a métodos.

 3
Author: Mike Two,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-24 13:08:39

Depende en gran medida del entorno en el que estés trabajando. Tomemos por ejemplo javascript. En javascript la mejor manera de pasar parámetros es usando objetos con pares clave/valor, lo que en la práctica significa que solo tiene un parámetro. En otros sistemas, el punto dulce será de tres o cuatro.

Al final, todo se reduce al gusto personal.

 1
Author: Joeri Sebrechts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:22:38

Estoy de acuerdo con que 3 está bien, 4 es demasiado como guía. Con más de 3 parámetros, inevitablemente está haciendo más de una tarea. Más de una tarea debe dividirse en métodos separados.

Sin embargo, si observara el último proyecto en el que he trabajado, las excepciones abundarían y la mayoría de los casos serían difíciles de reducir a 3 parámetros.

 1
Author: kae,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 16:25:02

Si tengo 7-10 parámetros en una rutina, miro agruparlos en una nueva clase pero no si esa clase no sería más que un montón de campos con getters y setters - la nueva clase tiene que hacer algo más que mezclar valores dentro y fuera. De lo contrario, prefiero soportar la larga lista de parámetros.

 1
Author: finnw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 17:02:08

Es un hecho conocido que, en promedio, la gente puede mantener 7 +/- 2 cosas en su cabeza a la vez. Me gusta usar ese principio con parámetros. Suponiendo que los programadores son personas inteligentes por encima del promedio, diría que todo 10 + es demasiado.

Por cierto, si los parámetros son similares de alguna manera, los pondría en un vector o lista en lugar de una estructura o clase.

 1
Author: Milan Babuškov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-06 17:38:58

Basaría mi respuesta en la frecuencia con la que se llama a la función.

Si es una función init que solo se llama una vez, entonces deje que tome 10 parms o más, a quién le importa.

Si se llama un montón de veces por fotograma, entonces tiendo a hacer una estructura y simplemente le paso un puntero, ya que tiende a ser más rápido ( suponiendo que no esté reconstruyendo la estructura cada vez también ).

 1
Author: KPexEA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-07 00:28:28

Según Jeff Bezos de Amazon fame, no más de lo que se puede alimentar con dos pizzas :

 1
Author: Kevin Pang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-07 00:45:09