Na página 45 do Código Limpo de Robert C. Martin: Manual do Artesanato em Software Ágil, Martin escreve que os argumentos de saída devem ser evitados. Estou tendo problemas para entender o significado de "argumento de saída" e por que eles devem ser evitados.
O exemplo de Martin para um argumento de saída appendFooter(s);
chama a função public void appendFooter(StringBuffer report)
. Sua melhoria do código éreport.appendFooter();
Talvez seja devido à falta de contexto do código, mas não vejo como usar argumentos de saída é considerado uma codificação ruim. Alguém poderia explicar o conceito ou dar um exemplo adicional de código para entender isso?
A função a seguir também seria considerada um exemplo de código impuro pelo princípio acima?
int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);
Se o exposto acima é uma violação do princípio de Martin de não usar argumentos de saída, seria melhor ter um objeto que tenha uma matriz como um campo e uma função que possa ser chamada para classificar a matriz?
ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();
fonte
sortArray(numberArray)
, é claro, classificanumberArray
no lugar. Ou ele faz uma cópianumberArray
, classifica a cópia e retorna a cópia classificada sem alterarnumberArray
nada?sort()
método de um contêiner também pode funcionar no local, sem usar um "argumento de saída". Portanto, apenas porquesortArray(numberArray)
é um método in-loco, não há absolutamente nenhuma razão que justifique o "formulário de argumento de saída".sortArray(numberArray)
está fazendo. Pode ser óbvio se ele não retornar o mesmo tipo que aceita, então ele deve estar no lugar. Mas sem ver o tipo de retorno, ou se o tipo de retorno corresponder ao tipo de entrada, não ficará claro sem examinar a definição.É uma questão de usar um mecanismo inesperado para retornar um valor da função, que geralmente é o resultado de fazer muito na função ou ter responsabilidades desalinhadas. De longe, a melhor maneira de comunicar o resultado de uma função é usar o valor de retorno. Espero que seja evidente. Nas linguagens orientadas a objetos, o segundo melhor método é alterar o objeto.
Entre essas duas opções, existem tantas maneiras claras e óbvias de comunicar o resultado de uma função que, se você quiser mudar os argumentos como o único meio, algo deu errado na sua arquitetura. Você precisa reorganizar suas responsabilidades de classe para que quem faz a mutação possua os dados em primeiro lugar.
A única exceção é para algoritmos muito genéricos. Por exemplo, um algoritmo de classificação pode ser legitimamente separado dos contêineres que classifica, se puder ser aplicado genericamente a qualquer tipo de contêiner usando sua interface pública. Uma
appendFooter
função de tiro único não tem essa desculpa.fonte