Question

Les routines peuvent avoir des paramètres, ce n'est pas une nouvelle. Vous pouvez définir autant de paramètres que nécessaire, mais trop nombreux rendront votre routine difficile à comprendre et à maintenir.

Bien sûr, vous pouvez utiliser une variable structurée comme solution de contournement: mettez toutes ces variables dans une même structure et transmettez-les à 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 dit:

  

Les programmeurs attentifs évitent de regrouper des données plus qu'il n'est logiquement nécessaire.

Donc, si votre routine a 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. C’est-à-dire que vous ne gardez pas le couplage lâche.

Ma question est la suivante: quand puis-je considérer une liste de paramètres trop volumineuse? je pense que plus de 5 paramètres sont trop nombreux. Qu'en penses-tu?

Était-ce utile?

La solution

Quand une chose est-elle considérée comme si obscène qu'elle peut être réglementée malgré la garantie du 1er amendement relative à la liberté d'expression? Selon le juge Potter Stewart, "je le sais quand je le vois". La même chose est valable ici.

Je déteste faire des règles strictes 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 votre méthode fait ou ce que la classe est supposée représenter, il est tout à fait possible que 2 arguments soient trop nombreux et constituent le symptôme d'un couplage excessif.

Je suggérerais qu'en posant la question en premier lieu et en qualifiant votre question autant que vous l'avez fait, vous savez vraiment tout cela. Dans ce cas, la meilleure solution consiste à ne pas compter sur un nombre exact et rapide, mais plutôt à rechercher des critiques de conception et de code parmi vos pairs afin d'identifier les zones où la cohésion et le couplage sont faibles.

N'ayez jamais peur de montrer votre travail à vos collègues. Si vous en avez peur, c’est probablement le signe le plus grave qui indique que quelque chose ne va pas dans votre code et que vous le savez déjà .

Autres conseils

Une fonction ne peut avoir trop de paramètres que si certains d'entre eux 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:

HWND CreateWindowEx
(
  DWORD dwExStyle,
  LPCTSTR lpClassName,
  LPCTSTR lpWindowName,
  DWORD dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  HWND hWndParent,
  HMENU hMenu,
  HINSTANCE hInstance,
  LPVOID lpParam
);

Cela représente 12 paramètres (9 si vous regroupez les x, y, w et h sous forme de rectangle) et les paramètres dérivés du nom de la classe. Comment réduiriez-vous cela? Voudriez-vous réduire le nombre plus précisément?

Ne laissez pas le nombre de paramètres vous déranger, assurez-vous que c'est logique et bien documenté et laissez intellisense * vous aider.

* D'autres assistants de codage sont disponibles!

Dans Clean Code , Robert C. Martin a consacré quatre pages au sujet . Voici l'essentiel:

  

Le nombre idéal d'arguments pour un   la fonction est zéro (niladique). Vient ensuite   un (monadique), suivi de près par deux   (dyadique). Trois arguments (triadiques)   devrait être évité autant que possible. Plus   que trois (polyadic) nécessite très   justification spéciale - et ensuite   ne devrait pas être utilisé de toute façon.

Certains codes avec lesquels j'ai travaillé auparavant utilisaient des variables globales simplement pour éviter de transmettre trop de paramètres.

S'il vous plaît, ne faites pas ça!

(généralement.)

Si vous commencez à compter mentalement les paramètres de la signature et à les faire correspondre à l'appel, il est temps de refactoriser!

Merci beaucoup pour toutes vos réponses:

Cette réponse suppose un langage OO. Si vous n’en utilisez pas un, ignorez cette réponse (en d’autres termes, ce n’est pas une réponse totalement agnostique.

Si vous transmettez plus de 3 paramètres environ (en particulier les types / objets intrinsèques), ce n’est pas qu’il s’agit de "Trop nombreux". mais que vous pouvez manquer une chance de créer un nouvel objet.

Recherchez des groupes de paramètres qui sont transmis à plus d'une méthode. Même un groupe passé à deux méthodes garantit presque la présence d'un nouvel objet.

Ensuite, vous refactorisez la fonctionnalité dans votre nouvel objet et vous ne croiriez pas à quel point cela aide votre code et votre compréhension de la programmation OO.

Il semble qu'il y ait d'autres considérations que le simple nombre, voici certaines qui me viennent à l'esprit:

  1. relation logique entre l'objectif principal de la fonction et les paramètres uniques

  2. S'ils ne sont que des indicateurs d'environnement, le regroupement peut s'avérer très pratique

L'un des épigrammes de programmation bien connus d'Alan Perlis (relatés dans l'avis 17 (9) de SIGPLAN de l'ACM, septembre 1982) indique que "Si vous avez une procédure avec 10 paramètres, vous en avez probablement oublié certaines."

Selon Steve McConnell dans Code Complete , vous devriez

  

Limiter le nombre de routines   paramètres à environ sept

Pour moi, lorsque la liste traverse une ligne de mon IDE, il y a un paramètre de trop. Je veux voir tous les paramètres dans une ligne sans rompre le contact visuel. Mais ce n’est que ma préférence personnelle.

Je suis généralement d'accord avec 5, cependant, s'il y a une situation dans laquelle j'ai besoin de plus et que c'est le moyen le plus clair de résoudre le problème, j'utiliserais plus.

Sept choses en mémoire à court terme?

  1. Nom de la fonction
  2. Valeur renvoyée de la fonction
  3. Objet de la fonction
  4. paramètre 1
  5. Paramètre 2
  6. paramètre 3
  7. paramètre 4

Dans 5 pires extraits de code , cochez la seconde" Est-ce un constructeur ". Il a comme plus de 37 & # 8901; 4 & # 8776; 150 paramètres:

  

Ici, un programmeur a écrit ce constructeur [...] Certains d'entre vous pensez peut-être que c'est un gros constructeur, mais il a utilisé des outils de génération de code automatique eclipse [.] NOO, dans ce constructeur, il y avait un petit bug que j'ai découvert, ce qui m'a fait conclure que ce constructeur avait été écrit à la main. (Au fait, ce n'est que la partie supérieure du constructeur, ce n'est pas complet).

     

constructeur avec plus de 150 paramètres

Un de plus que nécessaire. Je ne veux pas être désinvolte, mais certaines fonctions nécessitent nécessairement pas mal d'options. Par exemple:

void *
mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset);

Il y a 6 arguments, et chacun d’eux est essentiel. De plus, il n'y a pas de lien commun entre eux pour justifier leur regroupement. Vous pourriez peut-être définir "struct mmapargs", mais cela serait pire.

Selon les meilleures pratiques Perl , 3 convient, 4 est trop. Ce n'est qu'une ligne directrice, mais dans notre magasin, c'est ce que nous essayons de respecter.

Je dessinais moi-même la limite des fonctions publiques à 5 paramètres.

IMHO, les longues listes de paramètres ne sont acceptables que dans les fonctions d'assistance privées / locales qui ne doivent être appelées qu'à partir de quelques emplacements spécifiques du code. Dans ces cas, vous devrez peut-être transmettre beaucoup d'informations d'état, mais la lisibilité ne pose pas de problème, car vous seul (ou quelqu'un qui va gérer votre code et doit comprendre les principes fondamentaux de votre module) devez vous en soucier. appeler cette fonction.

Une question connexe à laquelle vous devriez vous intéresser est de savoir comment est cohérent . Un grand nombre de paramètres peut être une odeur qui vous dit que la routine elle-même essaie de faire trop et par conséquent que sa cohésion est suspecte. Je conviens qu’un nombre difficile de paramètres est probablement impossible, mais j’imagine qu’une routine de cohésion élevée impliquerait un petit nombre de paramètres.

97 sonne à merveille.

Moins et vous perdez la flexibilité.

Je m'arrête à trois paramètres en règle générale. Plus tard, il est temps de passer un tableau de paramètres ou un objet de configuration, ce qui permet également d'ajouter de nouveaux paramètres sans modifier l'API.

Une restriction de longueur sur une liste de paramètres n'est qu'une restriction de plus. Et restriction signifie violence appliquée. Cela semble drôle, mais vous pouvez être non violent même lorsque vous programmez. Laissez simplement le code dicter les règles. Il est évident que si vous avez plusieurs paramètres, le corps de la méthode function / class sera suffisamment grand pour pouvoir les utiliser. Et les gros extraits de code peuvent généralement être refactorisés et divisés en fragments plus petits. Vous avez donc la solution de ne pas avoir beaucoup de paramètres en tant que bonus gratuit, car ils sont répartis entre les plus petits morceaux de code refactorisés.

Du point de vue des performances, il est important de souligner que, selon la manière dont vous passez des paramètres à une méthode, le fait de passer beaucoup de paramètres par valeur ralentira le programme car chaque paramètre doit être copié puis placé dans la pile.

Utiliser une seule classe pour englober tous les paramètres fonctionnerait mieux car un seul paramètre passé par référence serait élégant, plus propre et plus rapide!

Selon moi, il pourrait y avoir des cas où vous dépassez 4 ou un nombre fixe. Les choses à surveiller pourraient être

  1. Votre méthode en fait trop et vous avez besoin de refactoriser.
  2. Vous pouvez envisager d'utiliser une collection ou une structure de données.
  3. Repensez la conception de votre classe, certaines choses n'ont peut-être pas besoin d'être transmises.

Du point de vue de la facilité d’utilisation ou de la lecture du code, je pense que vous devez un peu "insérer le texte". votre signature de méthode, qui 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 ne donnent aucun résultat. Certaines très bonnes bibliothèques du passé et du présent utilisent plus de 4 à 5 poussettes.

Ma règle générale est que je dois pouvoir me souvenir des paramètres suffisamment longtemps pour pouvoir regarder un appel et en expliquer le fonctionnement. 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 très brillant. Votre kilométrage peut varier.

Vous pouvez créer un objet avec des propriétés pour conserver les paramètres et le transmettre si vous dépassez la limite que vous avez définie. Voir Martin Fowler Refactoring et le chapitre sur la simplification des appels de méthode.

Cela dépend fortement de l'environnement dans lequel vous travaillez. Prenez par exemple le javascript. En javascript, le meilleur moyen de passer des paramètres consiste à utiliser des objets avec des paires clé / valeur, ce qui signifie en pratique que vous ne disposez que d'un paramètre. Dans d’autres systèmes, la limite idéale sera de trois ou quatre.

En fin de compte, tout se résume à vos goûts personnels.

Je suis d’accord avec 3 c’est bien, 4 c’est trop, à titre indicatif. 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 séparées.

Toutefois, si j’examinais le dernier projet sur lequel j’ai travaillé, les exceptions seraient légion et il serait difficile d’abaisser la plupart des cas à 3 paramètres.

Si je dispose de 7 à 10 paramètres dans une routine, je les regrouperais dans une nouvelle classe , mais , mais pas si cette classe ne serait qu'un tas de champs avec des getters et des setters - la nouvelle classe. doit faire autre chose que mélanger les valeurs. Sinon, je préférerais utiliser la longue liste de paramètres.

C’est un fait connu que, en moyenne, les gens peuvent garder 7 +/- 2 choses à la fois dans leur tête. J'aime utiliser ce principe avec des paramètres. En supposant que les programmeurs sont tous des personnes intelligentes supérieures à la moyenne, je dirais que tout ce qui est supérieur à 10, c'est trop.

BTW, si les paramètres sont similaires de quelque manière que ce soit, je les mettrais dans un vecteur ou une liste plutôt que dans une structure ou une classe.

Je baserais ma réponse sur la fréquence à laquelle la fonction est appelée.

S'il s'agit d'une fonction init qui n'est appelée qu'une fois, laissez-la prendre 10 parms ou plus, peu importe.

Si on l'appelle plusieurs 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).

Selon Jeff Bezos, d'Amazon, il n'y a pas plus que deux pizzas :

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top