Les routines peuvent avoir des paramètres, ce n'est pas une nouveauté. Vous pouvez définir autant de paramètres que nécessaire, mais un trop grand nombre d'entre eux rendra votre routine difficile à comprendre et à maintenir.
Bien sûr, vous pouvez utiliser une variable structurée comme solution de contournement: mettre toutes ces variables dans une seule structure et la passer à la routine. En fait, l'utilisation de structures pour simplifier les listes de paramètres est l'une des techniques décrites par Steve McConnell dans Code Complete . Mais comme il le dit:
Les programmeurs prudents évitent de regrouper les données plus qu'il n'est logiquement nécessaire.
Donc, si votre routine contient trop de paramètres ou si vous utilisez une structure pour masquer une grande liste de paramètres, vous faites probablement quelque chose de mal. Autrement dit, vous ne laissez pas le couplage desserré.
Ma question est, quand puis-je considérer une liste de paramètres trop grande? Je pense que plus de 5 paramètres, c'est trop. Qu'est-ce que tu penses?
Réponses:
Quand quelque chose est-il considéré comme obscène au point d'être réglementé malgré la garantie du 1er amendement à la liberté d'expression? Selon le juge Potter Stewart, "je le sais quand je le vois." Il en va de même ici.
Je déteste créer des règles dures et rapides comme celle-ci, car la réponse change non seulement en fonction de la taille et de la portée de votre projet, mais je pense que cela change même au niveau du module. Selon ce que fait votre méthode ou ce que la classe est censée représenter, il est fort possible que 2 arguments soit trop et soit un symptôme de trop de couplage.
Je dirais qu'en posant la question en premier lieu, et en nuançant votre question autant que vous, vous savez vraiment tout cela. La meilleure solution ici n'est pas de s'appuyer sur un nombre fixe et rapide, mais plutôt de rechercher des revues de conception et des revues de code entre vos pairs pour identifier les zones où vous avez une faible cohésion et un couplage serré.
N'ayez jamais peur de montrer à vos collègues votre travail. Si vous en avez peur, c'est probablement le plus gros signe que quelque chose ne va pas avec votre code, et que vous le savez déjà .
la source
Une fonction ne peut avoir trop de paramètres que si certains paramètres sont redondants. Si tous les paramètres sont utilisés, la fonction doit avoir le nombre correct de paramètres. Prenez cette fonction souvent utilisée:
Cela fait 12 paramètres (9 si vous regroupez les x, y, w et h sous forme de rectangle) et il y a aussi les paramètres dérivés du nom de la classe. Comment réduiriez-vous cela? Souhaitez-vous réduire davantage le nombre au point?
Ne laissez pas le nombre de paramètres vous déranger, assurez-vous simplement qu'il est logique et bien documenté et laissez Intellisense * vous aider.
* D'autres assistants de codage sont disponibles!
la source
Dans Clean Code , Robert C. Martin a consacré quatre pages au sujet. Voici l'essentiel:
la source
<algorithm>
je le ferais agir sur un objet range. Les collections seraient des plages, mais toutes les plages ne seraient pas des collections. Et en effet, boost l'a déjà fait. Quoi qu'il en soit, mon point est qu'une bibliothèque utilisée massivement largement ignore ce conseil, de sorte que le pire qui est garanti pour vous arriver si vous le faites aussi, est que beaucoup de vos millions d'utilisateurs vont bricoler avec Simplifications mineures à votre interface ;-)Certains codes avec lesquels j'ai travaillé dans le passé utilisaient des variables globales juste pour éviter de passer trop de paramètres.
Veuillez ne pas faire ça!
(Habituellement.)
la source
Si vous commencez à compter mentalement les paramètres de la signature et à les faire correspondre à l'appel, il est temps de refactoriser!
la source
Merci beaucoup pour toutes vos réponses:
C'était un peu surprenant de trouver des gens qui pensent aussi (comme moi) que 5 paramètres est une bonne limite pour la santé mentale du code.
Généralement, les gens ont tendance à penser qu'une limite entre 3 et 4 est une bonne règle de base. Ceci est raisonnable car les gens ont généralement du mal à compter plus de 4 choses.
Comme le souligne Milan , les gens peuvent en moyenne garder plus ou moins 7 choses en tête à la fois. Mais je pense que vous ne pouvez pas oublier que lorsque vous concevez / maintenez / étudiez une routine, vous devez garder à l'esprit plus de choses que les paramètres.
Certaines personnes considèrent qu'une routine doit avoir autant d'arguments que nécessaire. Je suis d'accord, mais seulement pour quelques cas spécifiques (appels aux API OS, routines où l'optimisation est importante, etc.). Je suggère de cacher la complexité de ces routines en ajoutant une couche d'abstraction juste au-dessus de ces appels chaque fois que possible.
pseudo a quelques réflexions intéressantes à ce sujet. Si vous ne voulez pas lire ses commentaires, je résume pour vous: en un mot, cela dépend :
La morale ici est de ne pas avoir peur de montrer votre code à vos pairs, de discuter avec eux et d'essayer de "d'identifier les zones où vous avez une faible cohésion et un couplage serré" .
Enfin, je pense que wnoise très d'accord avec Nick, et conclut sa contribution satirique avec cette vision poétique (voir commentaires ci-dessous) de l'art de la programmation:
la source
Cette réponse suppose un langage OO. Si vous n'en utilisez pas - sautez cette réponse (ce n'est pas tout à fait une réponse indépendante de la langue en d'autres termes.
Si vous passez plus de 3 paramètres environ (en particulier les types / objets intrinsèques), ce n'est pas que c'est "Trop" mais que vous manquez peut-être une chance de créer un nouvel objet.
Recherchez les groupes de paramètres qui sont passés dans plusieurs méthodes - même un groupe passé dans deux méthodes garantit presque que vous devriez y avoir un nouvel objet.
Ensuite, vous refactorisez la fonctionnalité dans votre nouvel objet et vous ne croiriez pas à quel point cela aide à la fois votre code et votre compréhension de la programmation OO.
la source
Il semble qu'il y ait d'autres considérations que le simple nombre, en voici quelques-unes qui me viennent à l'esprit:
relation logique avec l'objectif principal de la fonction par rapport aux paramètres uniques
S'ils ne sont que des indicateurs d'environnement, le regroupement peut être très pratique
la source
L'une des épigrammes de programmation bien connus d'Alan Perlis (racontée dans ACM SIGPLAN Notices 17 (9), septembre 1982) déclare que "si vous avez une procédure avec 10 paramètres, vous en avez probablement manqué quelques-uns".
la source
Selon Steve McConnell dans Code Complete , vous devriez
la source
Pour moi, lorsque la liste croise une ligne sur mon IDE, c'est un paramètre de trop. Je veux voir tous les paramètres sur une seule ligne sans rompre le contact visuel. Mais c'est juste ma préférence personnelle.
la source
Je suis généralement d'accord avec 5, cependant, s'il y a une situation où j'ai besoin de plus et que c'est le moyen le plus clair de résoudre le problème, alors j'en utiliserais plus.
la source
Sept choses dans la mémoire à court terme?
la source
Dans les pires extraits de code 5 , vérifiez le second, "Est-ce un constructeur". Il a comme plus de 37 ⋅ 4 ≈ 150 paramètres:
la source
Un de plus que nécessaire. Je ne veux pas être glib, mais il y a certaines fonctions qui nécessitent nécessairement pas mal d'options. Par exemple:
Il y a 6 arguments, et chacun d'eux est essentiel. De plus, il n'existe aucun lien commun entre eux pour justifier leur regroupement. Vous pourriez peut-être définir "struct mmapargs", mais ce serait pire.
la source
prot
etflags
auraient pu être regroupés si le concepteur avait estimé que 5 était en quelque sorte un nombre magique bien meilleur que 6. Un peu comme la façon quiopen
combine le mode lecture / écriture avec tous les autres drapeaux divers. Et peut-être toi pourriez débarrasseroffset
en spécifiant que la section mappée commence à la position de recherche actuelle defiledes
. Je ne sais pas s'il existe des situations où vous pouvezmmap
une région que vous n'êtes pas en mesure delseek
faire, mais sinon, ce n'est pas strictement nécessaire.mmap
c'est une bonne illustration du fait que certains concepteurs et utilisateurs préfèrent une longue liste de paramètres, tandis que d'autres préfèrent passer par quelques étapes pour préparer un plus petit nombre de paramètres avant de passer l'appel.Selon Perl Best Practices , 3 est correct, 4 est trop. C'est juste une directive, mais dans notre boutique, c'est ce que nous essayons de respecter.
la source
Je fixerais moi-même la limite des fonctions publiques à 5 paramètres.
À mon humble avis, les longues listes de paramètres ne sont acceptables que dans les fonctions d'assistance privées / locales qui sont uniquement destinées à être appelées à partir de quelques endroits spécifiques dans le code. Dans ces cas, vous devrez peut-être transmettre de nombreuses informations sur l'état, mais la lisibilité n'est pas un problème majeur car vous seul (ou quelqu'un qui maintiendra votre code et devrait comprendre les principes fondamentaux de votre module) doit se soucier de appeler cette fonction.
la source
Une question connexe que vous devriez considérer est de savoir comment cohérence de la routine. Un grand nombre de paramètres peuvent être une odeur qui vous indique que la routine elle-même essaie d'en faire trop et que sa cohésion est donc suspecte. Je suis d'accord qu'un nombre difficile et rapide de paramètres est probablement impossible, mais je suppose qu'une routine à forte cohésion impliquerait un faible nombre de paramètres.
la source
97 sonne à peu près juste.
Moins et vous perdez de la flexibilité.
la source
Je m'arrête à trois paramètres en règle générale. Plus et il est temps de passer un tableau de paramètres ou un objet de configuration à la place, ce qui permet également d'ajouter de futurs paramètres sans changer l'API.
la source
Une restriction de longueur sur une liste de paramètres n'est qu'une restriction de plus. Et la restriction signifie la violence appliquée. Cela peut sembler drôle, mais vous pouvez être non violent même lors de la programmation. Laissez simplement le code dicter les règles. Il est évident que si vous avez de nombreux paramètres, le corps de la méthode fonction / classe sera assez grand pour les utiliser. Et les gros extraits de code peuvent généralement être refactorisés et divisés en petits morceaux. Ainsi, vous obtenez une solution contre le fait d'avoir de nombreux paramètres en bonus gratuit, car ils sont répartis entre les petits morceaux de code refactorisés.
la source
Une chose que je voudrais souligner du point de vue des performances est que, selon la façon dont vous transmettez les paramètres à une méthode, le passage de nombreux paramètres par valeur ralentira le programme car chaque paramètre doit être copié puis placé sur la pile.
Utiliser une seule classe pour englober tous les paramètres fonctionnerait mieux car un seul paramètre transmis par référence serait élégant et plus propre, et plus rapide!
la source
Selon moi, il pourrait y avoir des cas où vous dépasseriez 4 ou un certain nombre fixe. Les choses à surveiller pourraient être
Du point de vue de la facilité d'utilisation ou de la facilité de lecture du code, je pense que lorsque vous devez "boucler" la signature de votre méthode, cela devrait vous faire réfléchir et vous arrêter, à moins que vous ne vous sentiez impuissant et que tous les efforts pour réduire la signature conduisent à pas de résultat. Certaines très bonnes bibliothèques dans le passé et le présent utilisent plus de 4 à 5 poussettes.
la source
Ma règle de base est que je dois pouvoir me souvenir des paramètres assez longtemps pour regarder un appel et dire ce qu'il fait. Donc, si je ne peux pas regarder la méthode, puis basculer vers un appel d'une méthode et me rappeler quel paramètre fait quoi, alors il y en a trop.
Pour moi, cela équivaut à environ 5, mais je ne suis pas si brillant. Votre kilométrage peut varier.
Vous pouvez créer un objet avec des propriétés pour contenir les paramètres et le transmettre si vous dépassez la limite que vous définissez. Voir le livre Refactoring de Martin Fowler et le chapitre sur la simplification des appels de méthode.
la source
Cela dépend fortement de l'environnement dans lequel vous travaillez. Prenez par exemple le javascript. En javascript, la meilleure façon de transmettre des paramètres est d'utiliser des objets avec des paires clé / valeur, ce qui signifie en pratique que vous n'avez qu'un seul paramètre. Dans d'autres systèmes, le sweet spot sera à trois ou quatre.
En fin de compte, tout se résume à un goût personnel.
la source
Je suis d'accord avec 3, ça va, 4 c'est trop comme guide. Avec plus de 3 paramètres, vous effectuez inévitablement plus d'une tâche. Plus d'une tâche doit être divisée en méthodes distinctes.
Cependant, si je regardais le dernier projet sur lequel j'ai travaillé, les exceptions seraient nombreuses et la plupart des cas seraient difficiles à ramener à 3 paramètres.
la source
Si j'ai 7 à 10 paramètres dans une routine, je cherche à les regrouper dans une nouvelle classe, mais pas si cette classe ne serait rien d'autre qu'un tas de champs avec des getters et des setters - la nouvelle classe doit faire autre chose que de mélanger les valeurs dans et en dehors. Sinon, je préfère accepter la longue liste de paramètres.
la source
C'est un fait connu que, en moyenne, les gens peuvent garder 7 +/- 2 choses dans leur tête à la fois. J'aime utiliser ce principe avec des paramètres. En supposant que les programmeurs sont tous des gens intelligents au-dessus de la moyenne, je dirais que tout 10+ est trop.
BTW, si les paramètres sont similaires en aucune façon, je les mettrais dans un vecteur ou une liste plutôt que dans une structure ou une classe.
la source
Je baserais ma réponse sur la fréquence à laquelle la fonction est appelée.
Si c'est une fonction init qui n'est appelée qu'une seule fois, laissez-la prendre 10 parms ou plus, peu importe.
Si cela s'appelle un tas de fois par image, j'ai tendance à créer une structure et à lui passer un pointeur car cela a tendance à être plus rapide (en supposant que vous ne reconstruisez pas la structure à chaque fois également).
la source
Selon Jeff Bezos de la renommée d'Amazon, rien ne peut être nourri avec deux pizzas :
la source