À la page 45 du code propre de Robert C. Martin: un manuel de fabrication de logiciels agiles, Martin écrit que les arguments de sortie doivent être évités. J'ai du mal à comprendre la signification de "l'argument de sortie" et pourquoi il faut les éviter.
L'exemple de Martin pour un argument de sortie appendFooter(s);
appelle la fonction public void appendFooter(StringBuffer report)
. Son amélioration du code estreport.appendFooter();
C'est peut-être dû au manque de contexte de code, mais je ne vois pas comment l'utilisation d'arguments de sortie est considérée comme un mauvais codage. Quelqu'un pourrait-il expliquer le concept ou donner un exemple supplémentaire de code pour comprendre cela?
La fonction suivante serait-elle également considérée comme un exemple de code impur selon le principe ci-dessus?
int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);
Si ce qui précède est une violation du principe de Martin de ne pas utiliser d'arguments de sortie, serait-il préférable d'avoir un objet qui a un tableau comme champ et une fonction qui peut être appelée pour trier le tableau?
ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();
la source
sortArray(numberArray)
, bien sûr, trienumberArray
en place. Ou fait-il une copie denumberArray
, trie la copie et retourne la copie triée sans la modifiernumberArray
du tout?sort()
méthode d'un conteneur peut également fonctionner sur place, sans utiliser un "argument de sortie". Donc, tout simplement parce qu'ilsortArray(numberArray)
s'agit d'une méthode sur place n'est absolument pas une raison qui justifie la "forme d'argument de sortie".sortArray(numberArray)
se passe. Cela peut être évident s'il ne retourne pas le même type qu'il accepte, alors il doit être en place. Mais sans voir le type de retour, ou si le type de retour correspond au type d'entrée, ce n'est pas clair sans regarder la définition.Il s'agit d'utiliser un mécanisme inattendu pour renvoyer une valeur de la fonction, ce qui est généralement le résultat de trop faire dans la fonction ou d'avoir des responsabilités mal alignées. De loin, la meilleure façon de communiquer le résultat d'une fonction est d'utiliser la valeur de retour. J'espère que cela va de soi. Dans les langages orientés objet, la deuxième méthode consiste à muter l'objet.
Entre ces deux options, il y a tellement de façons claires et évidentes de communiquer le résultat d'une fonction que si vous vous retrouvez à vouloir muter les arguments comme seul moyen, quelque chose a mal tourné dans votre architecture. Vous devez réorganiser vos responsabilités de classe afin que celui qui effectue la mutation soit propriétaire des données en premier lieu.
La seule exception concerne les algorithmes très génériques. Par exemple, un algorithme de tri peut à juste titre être séparé des conteneurs qu'il trie, s'il peut être appliqué de manière générique à tout type de conteneur à l'aide de son interface publique. Une
appendFooter
fonction ponctuelle n'a pas cette excuse.la source