En la página 45 del Código limpio de Robert C. Martin: Un manual de artesanía ágil de software, Martin escribe que los argumentos de salida deben evitarse. Tengo problemas para entender el significado de "argumento de salida" y por qué deberían evitarse.
El ejemplo de Martin para un argumento de salida appendFooter(s);
llama a la función public void appendFooter(StringBuffer report)
. Su mejora del código esreport.appendFooter();
Tal vez se deba a la falta de contexto de código, pero no veo cómo el uso de argumentos de salida se considera una codificación deficiente. ¿Podría alguien explicar el concepto o dar un ejemplo adicional de código para entender esto?
¿La siguiente función también se consideraría un ejemplo de código inmundo por el principio anterior?
int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);
Si lo anterior es una violación del principio de Martin de no usar argumentos de salida, ¿sería mejor tener un objeto que tenga una matriz como campo y una función a la que se pueda llamar para ordenar la matriz?
ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();
fuente
sortArray(numberArray)
, por supuesto, se ordenanumberArray
en su lugar. ¿O hace una copia denumberArray
, ordena la copia y devuelve la copia ordenada sin alterarnumberArray
en absoluto?sort()
método de contenedor también puede funcionar in situ, sin utilizar un "argumento de salida". Entonces, el hecho de quesortArray(numberArray)
sea un método en el lugar no es absolutamente ninguna razón que justifique la "forma de argumento de salida".sortArray(numberArray)
está haciendo. Puede ser obvio que si no devuelve el mismo tipo que acepta, entonces debe estar en su lugar. Pero sin ver el tipo de retorno, o si el tipo de retorno coincide con el tipo de entrada, no está claro sin mirar la definición.Se trata de utilizar un mecanismo inesperado para devolver un valor de la función, que generalmente es el resultado de hacer demasiado en la función o tener responsabilidades desalineadas. Con mucho, la mejor manera de comunicar el resultado de una función es usar el valor de retorno. Espero que sea evidente. En lenguajes orientados a objetos, el segundo mejor método es mutar el objeto.
Entre esas dos opciones, hay tantas formas claras y obvias de comunicar el resultado de una función que si alguna vez desea mutar los argumentos como el único medio, algo ha salido mal en su arquitectura. Debe reorganizar las responsabilidades de su clase para que el que realiza la mutación posea los datos en primer lugar.
La única excepción es para algoritmos muy genéricos. Por ejemplo, un algoritmo de ordenación podría estar separado de los contenedores que ordena, si se puede aplicar genéricamente a cualquier tipo de contenedor utilizando su interfaz pública. Una función de un solo disparo
appendFooter
no tiene esa excusa.fuente