En Clean Code, se escribe que "el número ideal de argumentos para una función es cero". Las razones por las cuales se explican y tienen sentido. Lo que busco es técnicas para refactorizar métodos con 4 o más argumentos para resolver este problema.
Una forma es extraer los argumentos en una nueva clase, pero eso seguramente conduciría a una explosión de clases. ¿Y es probable que esas clases terminen con nombres que violen algunas de las reglas de nomenclatura (que terminan en "Datos" o "Información", etc.)?
Otra técnica es hacer que las variables utilizadas por múltiples funciones sean una variable miembro privada para evitar pasarlas, pero eso expande el alcance de la variable, posiblemente de tal manera que esté abierta a funciones que realmente no la necesitan.
Simplemente buscando maneras de minimizar los argumentos de la función, habiendo aceptado las razones por las cuales es una buena idea hacerlo.
fuente
Respuestas:
Lo más importante para recordar es que son pautas, no reglas.
Hay casos en que un método simplemente debe tomar un argumento. Piense en el
+
método para los números, por ejemplo. O eladd
método para una colección.De hecho, incluso se podría argumentar que lo que significa agregar dos números depende del contexto, por ejemplo, en ℤ
3 + 3 == 6
, pero en ℤ | 53 + 3 == 2
, por lo que realmente el operador de suma debería ser un método en un objeto de contexto que toma dos argumentos en lugar de un método en números que toma un argumento.Del mismo modo, un método para comparar dos objetos debe ser un método de un objeto tomando al otro como argumento, o un método del contexto, tomando dos objetos como argumentos, por lo que simplemente no tiene sentido tener un método de comparación con menos de un argumento
Dicho esto, hay un par de cosas que se pueden hacer para reducir la cantidad de argumentos para un método:
Point
objeto o, en lugar de pasar el nombre de usuario y el correo electrónico, pase unIdCard
objeto).Si su modelo de dominio tiene muchos tipos diferentes de cosas, entonces su código terminará con muchos tipos diferentes de objetos. No hay nada de malo en eso.
Si no puede encontrar un nombre propio, quizás haya agrupado demasiados argumentos o muy pocos. Entonces, o tienes solo un fragmento de una clase o tienes más de una clase.
Si tiene un grupo de métodos, todos los cuales operan con los mismos argumentos, y otro grupo de métodos que no lo hacen, tal vez pertenezcan a diferentes clases.
Tenga en cuenta con qué frecuencia usé la palabra "tal vez"? Es por eso que son pautas, no reglas. ¡Quizás tu método con 4 parámetros está perfectamente bien!
fuente
add
función para números naturales y laadd
función para el anillo de números enteros mod n son dos acciones de funciones diferentes en dos tipos diferentes. Tampoco entiendo lo que quieres decir con "contexto".Tenga en cuenta que los argumentos cero no implican efectos secundarios, porque su objeto es un argumento implícito. Mire cuántos métodos de aridad cero tiene la lista inmutable de Scala , por ejemplo.
Una técnica útil que llamo la técnica de "enfoque de lente". Cuando enfoca la lente de una cámara, es más fácil ver el verdadero punto de enfoque si lo lleva demasiado lejos, luego lo retrocede al punto correcto. Lo mismo se aplica a la refactorización de software.
Especialmente si está utilizando el control de versiones distribuido, los cambios de software son fáciles de experimentar, vea si le gusta cómo se ven y retroceda si no lo hace, pero por alguna razón la gente a menudo parece reacia a hacerlo.
En el contexto de su pregunta actual, eso significa escribir las versiones de argumento cero o uno, con varias funciones separadas primero, luego es relativamente fácil ver qué funciones deben combinarse para facilitar la lectura.
Tenga en cuenta que el autor también es un gran defensor del desarrollo impulsado por pruebas, que tiende a producir funciones de baja aridad al principio porque comienza con sus casos de prueba triviales.
fuente
Un enfoque que simplemente (e ingenuamente, o incluso debería decir a ciegas ) solo apunta a reducir el número de argumentos a las funciones, probablemente no sea correcto. No hay absolutamente nada de malo en que las funciones tengan una gran cantidad de argumentos. Si la lógica los requiere, bueno, son necesarios ... Una larga lista de parámetros no me preocupa en absoluto, siempre que esté correctamente formateada y comentada para facilitar su lectura.
En el caso de que todos o un subconjunto de argumentos pertenezcan a una entidad lógica única y se transmitan comúnmente en grupos a lo largo de su programa, quizás tenga sentido agruparlos en algún contenedor, generalmente una estructura u otro objeto. Los ejemplos típicos pueden ser algún tipo de mensaje o tipo de datos de evento .
Puede exagerar fácilmente ese enfoque: una vez que encuentre que empacar y desempacar cosas hacia y desde dichos contenedores de transporte genera más sobrecarga que mejora la legibilidad, probablemente haya ido demasiado lejos.
OTOH, las listas de parámetros grandes pueden ser una señal de que su programa puede no estar estructurado adecuadamente; tal vez la función que requiere una cantidad tan grande de parámetros solo está tratando de hacer demasiado y debería dividirse en varias funciones más pequeñas. Prefiero comenzar aquí que preocuparme por # de parámetros.
fuente
No hay una forma mágica: debe dominar el dominio del problema para descubrir la arquitectura correcta. Esa es la única forma de refactorizar: dominar el dominio del problema. Más de cuatro parámetros es solo una apuesta segura de que su arquitectura actual es defectuosa e incorrecta.
Las únicas excepciones son los compiladores (metaprogramas) y las simulaciones, donde el límite es teóricamente 8, pero probablemente solo 5.
fuente