web-dev-qa-db-fra.com

Directive de codage: les méthodes ne doivent pas contenir plus de 7 énoncés?

Je regardais les AvSol Coding Guidelines pour C # et je suis d'accord avec presque tout mais je suis vraiment curieux de voir ce que les autres pensent d'une règle spécifique.

AV1500

Les méthodes ne doivent pas dépasser 7 énoncés Une méthode qui nécessite plus de 7 énoncés fait trop ou a trop de responsabilités. Cela nécessite également que l'esprit humain analyse les déclarations exactes pour comprendre ce que fait le code. Décomposez-le en plusieurs petites méthodes ciblées avec des noms explicites.

La plupart d'entre vous suivent-ils cette règle? Même s'il y a peu à économiser de la création d'une nouvelle méthode (votre code est toujours SEC ) à part une lisibilité considérablement accrue? Et votre nombre est-il aussi bas que 7? J'aurais plutôt tendance vers 10.

Je ne dis pas que je viole cette règle partout - au contraire, mes méthodes sont petites à 95% et concentrées, mais dire que vous ne devriez jamais violer cette règle m'a vraiment époustouflé.

Je veux vraiment savoir ce que tout le monde pense de ne JAMAIS enfreindre cette règle (c'est un "1" sur la norme de codage - ce qui signifie NE JAMAIS faire cela). Mais je pense que vous auriez du mal à trouver une base de code qui ne fonctionne pas.

80
brian

C'est une "odeur standard" pour moi. Chaque fois que je vois des normes de codage avec des limites spécifiques, je m'inquiète. Vous rencontrez presque toujours un cas où une méthode doit être plus grande que la norme ne le permet (que ce soit la longueur/le nombre de lignes, le nombre de variables, le nombre de points de sortie, etc.). Les normes devraient ressembler davantage à des directives et laisser une marge de manœuvre suffisante pour exercer un bon jugement. Ne vous méprenez pas, c'est bien d'avoir des standards, mais ils ne doivent pas devenir "microgestion par proxy".

195
TMN

C'est généralement une bonne idée de diviser les choses en petites méthodes. Mais l'important est de diviser les choses là où cela a du sens.

Si cela n'a pas de sens de diviser, alors ne divisez pas. C'est souvent le cas pour certaines procédures ou code GUI.

Steve McConnell a déclaré dans Code Complete que vous n'êtes pas toujours plus productif lorsque vous utilisez des méthodes courtes. Si vous vous séparez quand cela n'a pas de sens, vous ajoutez de la complexité au code sans aucun avantage.

Comme toujours avec les directives, il est bon de se rappeler pourquoi les contraintes existent, afin que vous puissiez apprendre quand elles ne s'appliquent pas. Dans la plupart du code, les méthodes seront courtes, ou vous avez probablement un problème avec DRY ou séparation des préoccupations . Mais si ce n'est pas le cas, alors très bien .

83
deadalnix

Cela devrait être considéré comme une règle de base.

Des choses comme "pas plus de 80 (100 120) colonnes de texte", "un point de sortie par méthode", "pas plus de 2 niveaux d'imbrication", sont ce que j'appellerais des seuils pour les indicateurs de l'odeur du code. Si vous les violez à l'occasion, cela ne signifie pas nécessairement que le code est mauvais. Si vous vous trouvez en train de les violer de manière cohérente, alors quelque chose sent dans le code et vous pouvez souhaiter faire une pause et repenser votre approche.

Pour moi, les critères les plus importants sont: "Ce code est-il compréhensible?", "Est-il répétitif?", "Est-il décomposé en des endroits logiques?", "Est-il faiblement couplé?" Il y en a quelques autres, mais je pense que l'idée de base peut être résumée en se souvenant des conseils de Donald Knuth: "Les programmes sont destinés à être lus par les humains et seulement accessoirement aux ordinateurs à exécuter."

29
seggy

Je n'ai jamais pris le temps de compter le nombre d'instructions dans mes méthodes, mais je m'efforce d'écrire des méthodes qui exécutent proprement un seul objectif clair. Tant que votre code est propre, lisible et respecte les principes SEC et responsabilité unique , vous avez probablement fait votre travail . Je pense que séparer arbitrairement une méthode juste pour appliquer la limite de sept instructions pourrait rendre votre code moins lisible/maintenable.

18
Joshua Smith

C'est approximatif

Ce genre de règles ne doit pas être pris trop à la lettre. Ils auraient pu dire "les méthodes devraient être courtes". Cependant, certaines personnes auraient interprété cela comme "moins d'une page" et d'autres comme "2 lignes au maximum".

je suppose qu'ils ont dit "7 déclarations" pour vous donner une idée approximative (bien que je pense qu'ils auraient dû dire "environ 7"). Si vous avez besoin de 9 fois de temps en temps, ne le transpirez pas. Mais si vous atteignez 20, vous saurez que vous n'êtes pas dans le bon stade pour cette règle.

11
Nathan Long

7 est un nombre complètement arbitraire sans aucune signification.

Complexité cyclomatique est un problème plus important que le nombre d'instructions. J'ai vu du code qui avait des centaines d'instructions dans une seule méthode (ce que je pensais être terrible), mais il avait une complexité cyclomatique de 1 et il ne faisait vraiment qu'une chose. Il y avait juste beaucoup d'étapes. Nous avons discuté de le séparer en méthodes plus petites, mais ces méthodes ne seraient appelées que par cette seule méthode.

Bien que ce soit un cas assez extrême, le fait est que vous devez conserver le code DRY et une faible complexité cyclomatique. C'est plus important que le nombre de lignes dans une méthode.

Prenons par exemple une instruction switch/case. Si vous avez plus de 7 valeurs possibles, devez-vous diviser l'évaluation en plusieurs méthodes? Bien sûr que non, ce serait idiot.

Diviser artificiellement le code en plusieurs méthodes juste pour maintenir le nombre d'instructions sous 7 ne fait qu'aggraver votre code.

La directive doit être Chaque méthode doit faire 1 chose et garder votre code SEC.

10
Jim McKeeth

Eh bien, ça dépend un peu. J'écris beaucoup de code qui accède aux bases de données. Le code de la plaque de la chaudière pour la gestion des exceptions est plus de sept déclarations dans de nombreux cas. Je dirais que la meilleure ligne directrice est de vous assurer que votre fonction a un but

4
Jaydee

Tout est un compromis. Le problème avec l'approche proposée - la refactorisation en plusieurs méthodes et classes afin que chaque méthode soit courte - est que, bien que pour des raisons différentes, elle mène à un code illisible lorsqu'elle est poussée à son extrême.

Imaginez une méthode foo() qui fait 7 choses. Vous pourriez dire que 7 choses, c'est trop. Dans de nombreux cas, vous avez peut-être raison. D'un autre côté, ces 7 choses pourraient être étroitement liées; la logique peut couler en douceur et se lire comme de la prose; vous n'aurez peut-être aucun mal à le comprendre lorsque vous en aurez réellement besoin. Ce qui pourrait finir bien pire, c'est d'avoir ces 7 choses réparties sur une grande arborescence source, de sorte que si vous regardez foo() vous n'avez aucune idée de ce qu'il fait sans regarder dans 7 endroits différents.

Beaucoup de gens ont des règles comme ça dans leur tête, et le résultat est ce que je pense comme OO spaghetti. Tout est soigné, encadré dans sa propre petite méthode ou classe, avec de petites micro-transactions atomiques mais il est impossible de revenir à une telle base de code et de savoir ce qu'elle fait. Vous vous perdez.

4
asveikau

ce n'est pas une mauvaise directive. Je n'ai jamais regretté d'avoir divisé des méthodes et des classes (je n'en ai jamais trouvé trop) tant qu'elles sont suffisamment regroupées et interreliées.

L'astuce consiste à ne PAS la diviser verticalement (il suffit de pincer une méthode à un moment donné et d'en démarrer une nouvelle). L'astuce, comme avec les tests unitaires, est de garder une telle règle à l'esprit dès le début afin que vous conceviez réellement mieux, en passant 3 ou 4 instructions en cours de méthode à une autre méthode, car avoir un appel de méthode décrit ce que vous faites mieux que ces 3 ou 4 déclarations au milieu de votre code.

Ce type de fractionnement, même s'il est arbitraire et utilisé une seule fois, peut conduire à de meilleurs refactorings plus tard en raison d'une nouvelle clarté de code, cela est également vrai pour les classes plus petites.

Pensez-y comme vous le feriez pour des tests unitaires. Si vous essayez d'ajouter des tests unitaires après coup, c'est difficile et semble parfois impossible, mais si vous le concevez depuis le début, cela améliore en fait tout votre code.

Sommaire? Si vous comparez l'odeur de conception "Utiliser moins de 7 instructions" à l'odeur de code "J'ai utilisé plus de 7 instructions", je préfère éliminer l'odeur de code.

4
Bill K

Hou la la! Je ne m'attendais pas à trouver une discussion aussi intense sur une ligne directrice simple qui dit à peu près que vos méthodes devraient être très petites. Parce que ce sont toujours des développeurs qui veulent que leurs directives soient explicites, je choisis 7 parce que ça sonnait comme un seuil de Nice.

Certains d'entre vous ont déjà cité l'avertissement au début du document. Mais pour être clair, ce document représente une collection de directives qui essaient de vous aider à écrire un meilleur code et à concevoir de meilleurs systèmes. Je n'ai jamais dit que quoi que ce soit devrait être une règle, même si une directive est marquée comme un niveau 1. Ces niveaux sont simplement l'opinion collective des nombreuses personnes qui utilisent ce document depuis un certain temps.

Je n'ai également jamais prétendu être un expert. Mais je suis dans cette profession depuis 15 ans maintenant, avec environ 4 ans d'expérience en C++ et 11 ans d'expérience en C #. Il était à l'origine basé sur Industrial Strength C++, mais je l'ai affiné depuis lors avec la contribution de la communauté.

Quoi qu'il en soit, le point que j'essayais de soulever est que vous devriez continuer à penser par vous-même. Si vous pensez que la ligne directrice des 7 énoncés n'est pas utile, prolongez-la simplement. Heck, je viole même cette directive de temps en temps. Je ne fais que la violer de manière conséquente et j'accepte les conséquences.

4
Dennis Doomen

Premièrement: c'est une ligne directrice, pas une règle. Cela s'appelle une directive, alors veuillez la traiter comme telle. Cela implique que votre propre jugement est également requis (comme toujours)

Cela mis à part, je peux penser à de nombreux exemples de bon code qui n'adhère pas à cette contrainte. Même si ce n'est qu'une directive, c'est une mauvaise.

3
Dominic Cronin

Assez stupide lorsque vous ajoutez une manipulation d'exception au mélange.

Après "essayer, attraper, enfin", vous vous retrouvez avec quatre instructions par méthode!

Considérez également une méthode "validateForm" pour un formulaire de 20 champs, même si vous gérez toutes les validations individuelles dans des méthodes distinctes, vous avez encore 20 méthodes de validation de champ à invoquer. Selon ces lignes directrices, vous vous retrouveriez avec une division inutile comme "validateTopOfScreen", "validateMiddleOfScreen" et "validateBottomOfScreen".

2
James Anderson

La question confond les "règles" et les "directives". Les règles sont censées être respectées - les lignes directrices sont des conseils qui visent à vous faire réfléchir à ce que vous faites et si cela pourrait vraiment être fait d'une meilleure manière.

Je dirais qu'en moyenne, la plupart des programmes sont probablement améliorés en suivant les directives, mais il y aura toujours des cas où suivre les directives de manière dogmatique causera plus de problèmes que prévu. C'est pourquoi elles ne sont pas présentées comme des règles, mais comme des lignes directrices.

Un intervenant précédent a montré que les rédacteurs des lignes directrices n'avaient jamais voulu qu'elles soient appliquées de manière dogmatique et ont inclus des déclarations à cet effet dans leur document.

2
authentictech

Je suis d'accord avec la déclaration ci-dessus. C'est juste une ligne directrice et dans un monde parfait, tout serait des objets, réutilisés dans chaque programme, et le monde serait un bel endroit. Ce n'est pas toujours vrai et parfois cela entraînerait beaucoup de frais généraux ou de gaspillage de ressources. Vous devez également garder cela à l'esprit.

2
Falcon165o

Mauvaise règle. Avec le code pour la gestion des exceptions, la définition des champs de base de données, la validation, comment la plupart des méthodes peuvent-elles contenir moins de sept instructions? Ne devrions-nous jamais faire des fonctions lambda en ligne?

Les lignes de code sont un nombre arbitraire de complexité. Avec des méthodes d'extension, je peux créer du code comme

                Parallel.ForEach(regions, region => {   Console.Write(region.Resorts.Where(x => x.name == "Four Seasons").OrderBy(x => x.RegionId).ThenBy(x => x.ResortId).ThenBy(x => x.name).ToList());   });
0
Justin

Je suis d'accord avec soe des commentaires ci-dessus. 7 pour moi est arbitraire et peut être utile dans certains langages où Ruby, mais pour des langages comme C #, Java, C++ je doute de cette convention "7 lignes". Permettez-moi de vous donner un exemple. Ma demande actuelle comporte 22 champs de texte et je fais la validation côté serveur. La méthode est appelée validateInput () et ma préférence est de valider tous les champs dans une méthode elle-même, sauf si j'ai validé quelque chose de complexe comme checkEmailFormat (). Donc, fondamentalement, mon code de méthode validateInput est de 108 lignes avec des appels occasionnels à une validation complexe.

Imaginez maintenant si j'appelais 25 méthodes pour valider chaque champ. Si un nouveau développeur arrive, il devra entrer et sortir de la méthode principale pour passer à travers 25 méthodes qui à leur tour pourraient en appeler quelques autres. Il va se perdre dans de grands projets.

Ce que je fais vraiment pour que mon code soit clair, c'est de fournir des commentaires clairs qui disent essentiellement ce que font ces 4 lignes ex -

validateInput (utilisateur UserObj) {

// Validez le prénom ....... ......

// valider le nom de famille ...... ......

// valider l'e-mail ..... // trop complexe pour vérifier le format de l'e-mail expression régulière checkEmailFormat (); .... .....

etc.. }

0
Dinesh Arora