Je parcourais les directives de codage AvSol pour C # et je suis d’accord sur 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 en 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écoupez-le en plusieurs méthodes petites et ciblées avec des noms qui s’expliquent.
Est-ce que la plupart d'entre vous suivent cette règle? Même s'il y a peu de choses à sauver de la création d'une nouvelle méthode (votre code est toujours sec ) en dehors d'une augmentation considérable de la lisibilité? Et votre nombre est-il toujours aussi bas que 7? J'aurais tendance plus vers 10.
Je ne dis pas que je viole cette règle dans tous les sens - au contraire, mes méthodes sont à 95% petites et concentrées, mais en disant que vous ne devriez jamais enfreindre cette règle m'a vraiment sidéré.
Je veux vraiment juste savoir ce que tout le monde pense de NE JAMAIS violer cette règle (c'est un «1» sur la norme de codage - ce qui signifie NE JAMAIS le faire). Mais je pense que vous auriez du mal à trouver une base de code qui ne l’ait pas.
case
déclarations en une seule foisswitch
? Quoi qu’il en soit, ce n’est rien qu’une exigence idiote et inutile. Ceux qui l'ont écrit ne connaissent rien à la programmation.Réponses:
Ceci est une "odeur de normes" pour moi. Chaque fois que je vois des normes de codage comportant des limites spécifiques, cela m'inquiète. Vous rencontrez presque toujours le cas où une méthode doit être supérieure à la norme (qu'il s'agisse de la longueur / du nombre de lignes, du nombre de variables, du 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. Comprenez-moi bien, c'est bien d'avoir des normes, mais elles ne devraient pas devenir "microgestion par procuration".
la source
Guidlines
for C # 3.0 and 4.0."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 fait sens.
Si la scission n'a pas de sens, ne la divisez pas. C'est souvent le cas pour certaines procédures ou codes d'interface graphique.
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 lorsque 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, ainsi vous pourrez apprendre quand cela ne s'applique pas. Dans la plupart des codes, les méthodes seront courtes ou vous aurez probablement un problème de DRY ou de séparation des problèmes . Mais si ce n'est pas le cas, alors d'accord.
la source
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 d'odeur de code. Si vous les violez à l'occasion, cela ne signifie pas nécessairement que le code est mauvais. Si vous vous retrouvez en train de les violer systématiquement, quelque chose sent le code et vous voudrez peut-être prendre 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 divisé en plusieurs endroits logiques?", "Est-il couplé de manière lâche?" Il y en a quelques autres, mais je pense que l'idée de base peut être résumée en se rappelant le conseil de Donald Knuth: "Les programmes sont destinés à être lus par des humains et, accessoirement, par des ordinateurs à exécuter."
la source
less
, dansvim
etemacs
; et l'emballage automatique semble au mieux hasard. Les normes de codage ne sont pas pour vous, mais pour les personnes qui travaillent en équipe.Je n'ai jamais pris le temps de compter le nombre d'énoncés dans mes méthodes, mais je m'efforce d'écrire des méthodes qui remplissent proprement un objectif unique et clair. Tant que votre code est propre, lisible et conforme aux principes DRY et Single Responsibility , vous avez probablement fait votre travail. Je pense que séparer arbitrairement une méthode pour appliquer la limite de sept instructions risque de rendre votre code moins lisible / maintenable.
la source
C'est approximatif
Ce genre de règles ne devrait pas être pris à 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 "deux lignes au plus".
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 de temps en temps, ne vous en faites pas. Mais si vous atteignez 20, vous saurez que vous n'êtes pas dans la bonne fourchette pour cette règle.
la source
7 est un nombre complètement arbitraire sans aucune signification.
La complexité cyclomatique est un problème plus important que le nombre d'énoncés. J'ai vu du code contenant une centaine d'énoncés dans une seule méthode (ce que j'ai trouvé terrible), mais il comportait une complexité cyclomatique de 1 et ne comportait qu'une seule chose. Il y avait juste beaucoup d'étapes. Nous avons discuté de le diviser en méthodes plus petites, mais ces méthodes ne seraient appelées que par cette méthode.
Bien que ce soit un cas assez extrême, le fait est que vous devez conserver le code DRY et une complexité cyclomatique faible. C'est plus important que le nombre de lignes d'une méthode.
Prenons une instruction switch / case par exemple. 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 davantage de méthodes simplement pour conserver le nombre d'instructions inférieur à 7 ne fait qu'aggraver votre code.
La ligne directrice devrait être Chaque méthode doit faire 1 chose et garder votre code SEC.
la source
Ça dépend un peu. J'écris beaucoup de code qui accède aux bases de données. Le code de la plaque de chaudière pour la gestion des exceptions est plus de sept déclarations longues dans de nombreux cas. Je dirais que la meilleure ligne directrice est de vous assurer que votre fonction a un but
la source
ps
etrs
et enregistrez les uns les autres. Vous pouvez également écrire une méthodeList<Row> readDb(String sql, Object... args)
qui exécute tout le travail (fonctionne uniquement pour les ensembles de résultats insérés en mémoire, mais extraire trop de données implique généralement que le travail soit effectué dans la base de données de toute façon).Tout est un compromis. Le problème de l’approche proposée - refactoring en plusieurs méthodes et classes afin que chaque méthode soit brève - est que, bien que pour des raisons différentes, elle conduit à un code illisible à l’extrême.
Imaginez une méthode
foo()
qui fait 7 choses. Vous pourriez soutenir que 7 choses, c'est trop. Peut-être que dans de nombreux cas, vous avez raison. D'autre part, ces 7 choses pourraient être étroitement liées; la logique peut être fluide et se lire comme une prose; vous n'aurez peut-être pas de difficulté à comprendre quand vous en aurez réellement besoin. Ce qui pourrait finir par être bien pire, c’est de répartir ces 7 éléments sur une grande arborescence de sources, de sorte que vousfoo()
n’ayez aucune idée de ce que cela fait sans regarder dans 7 endroits différents.Beaucoup de gens ont des règles comme celle-ci dans leur tête, et le résultat est ce que je pense être du spaghetti OO. Tout est soigné, encadré dans sa propre petite méthode ou classe, avec de petites micro-transactions atomiques se produisant à chaque endroit. Mais il est impossible de revenir à une telle base de code et de savoir ce qu'il fait. Tu te perds.
la source
ce n'est pas une mauvaise directive. Je n'ai jamais regretté de séparer les méthodes et les classes (je n'ai jamais trouvé que j'en ai eu trop) tant qu'elles sont groupées et suffisamment inter-reliées.
L'astuce consiste à NE PAS la scinder verticalement (il suffit de pincer une méthode à un moment donné et d'en commencer une nouvelle). Comme dans le cas des tests unitaires, l’astuce consiste à garder une telle règle à l’esprit dès le départ pour mieux concevoir, en passant 3 à 4 instructions en méthode à une autre méthode, car avoir un appel de méthode décrit mieux ce que vous faites. ces 3 ou 4 déclarations au milieu de votre code.
Ce type de scission, même s'il est arbitraire et utilisé une seule fois, peut conduire à de meilleurs refactorisations ultérieurement en raison d'une nouvelle clarté du code, cela s'applique également aux petites classes.
Pensez-y comme aux tests unitaires. Si vous essayez d'ajouter des tests unitaires après le fait, c'est difficile et cela semble parfois impossible, mais si vous le concevez depuis le début, tout votre code sera amélioré.
Sommaire? Si vous comparez l'odeur de "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.
la source
Hou la la! Je ne m'étais jamais attendu à trouver une discussion aussi intense sur une simple directive qui dit grossièrement que vos méthodes devraient être très petites. Parce qu'ils sont toujours des développeurs qui veulent que leurs directives soient explicites, j'ai choisi 7 parce que cela semblait être un bon seuil.
Certains d'entre vous ont déjà cité l'avertissement au début du document. Mais juste pour être clair, ce document représente un ensemble de directives qui essaient de vous aider à écrire un meilleur code et à concevoir de meilleurs systèmes. Je n'ai jamais dit que quelque chose devrait être une règle, même si une ligne directrice est marquée comme un niveau 1. Ces niveaux représentent simplement l'opinion collective des nombreuses personnes qui utilisent ce document depuis un certain temps.
De plus, je n'ai jamais prétendu être un expert. Mais je suis dans ce métier depuis 15 ans maintenant, avec environ 4 ans d’expérience C ++ et 11 ans d’expérience C #. Il était à l'origine basé sur Industrial Strength C ++, mais je l'affine depuis lors avec la participation de la communauté.
Quoi qu’il en soit, ce que j’essayais de dire, c’est que vous devriez continuer à penser par vous-même. Si vous pensez que la directive des 7 énoncés n’est pas utile, il suffit de la prolonger. Heck, je viole même cette directive de temps en temps. Je viens de le violer consciemment et accepter les conséquences.
la source
Premièrement: c'est une ligne directrice, pas une règle. C'est ce qu'on appelle une ligne directrice, alors s'il vous plaît, traitez-le comme tel. Cela implique que votre propre jugement est également requis (comme toujours)
Cela mis à part, je peux penser à de nombreux exemples de code de qualité qui ne respecte pas cette contrainte. Même si ce n'est qu'une ligne directrice, c'est une pauvre.
la source
Je suis d'accord avec la déclaration ci-dessus. Ce ne sont que des lignes directrices et, dans un monde parfait, tout serait un objet, réutilisé dans chaque programme, et le monde serait un endroit magnifique. Ce n'est pas toujours vrai et cela peut parfois entraîner beaucoup de frais généraux ou de gaspillage de ressources. Vous devez également tenir compte de cela.
la source
Assez ridicule quand vous ajoutez la gestion des exceptions dans le mélange.
Après "essayer, attraper, enfin" vous vous retrouvez avec quatre déclarations 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 à appeler. Selon ces directives, vous vous retrouveriez avec une scission inutile comme "validateTopOfScreen", "validateMiddleOfScreen" et "validateBottomOfScreen".
la source
try
/catch
/finally
ne sont pas des déclarations en C #. Voir Ecma-334 § 12.3.3.15 et les sections environnantes. ( en abrégé) " un try-catch-finally de la forme : essayez bloc try catch (...) bloc catch-n finalement finalement bloc "La question est de confondre "règles" avec "lignes directrices". Les règles sont censées être respectées - les directives sont des conseils destinés à vous amener à réfléchir à ce que vous faites et à déterminer si cela pourrait être fait d'une meilleure façon.
Je dirais que, en moyenne, la plupart des programmes sont probablement améliorés en suivant les lignes directrices, mais il y aura toujours des cas où suivre les lignes directrices de manière dogmatique causera plus de problèmes qu'ils ne devaient en résoudre. C'est pourquoi elles ne sont pas présentées comme des règles, mais comme des directives.
Un répondant précédent a montré que les rédacteurs des directives n’avaient jamais eu l’intention de les appliquer de manière dogmatique et ont inclus des déclarations à cet effet dans leur document.
la source
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". Laissez-moi vous donner un exemple. Mon application actuelle a 22 champs de texte et je fais une validation côté serveur. La méthode s'appelle validateInput () et ma préférence est de valider tous les champs d'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 constitué de 108 lignes avec des appels occasionnels à une validation complexe.
Maintenant, imaginez si j'ai appelé 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 est voué à se perdre dans les grands projets.
Ce que je fais vraiment pour que mon code soit clair est de fournir des commentaires clairs qui disent en gros ce que ces 4 lignes font ex -
validateInput (utilisateur UserObj) {
// Valider le prénom ....... ......
// valider le nom ...... ......
// valider l'email ..... // trop complexe pour vérifier le format d'email expression régulière checkEmailFormat (); ..... .....
etc.. }
la source
Mauvaise règle. Avec du code pour la gestion des exceptions, la définition des champs de la base de données, la validation, comment la plupart des méthodes peuvent-elles être sous sept instructions? Ne devrions-nous jamais faire de fonctions lambda en ligne?
Les lignes de code sont un décompte arbitraire de complexité. Avec les méthodes d'extension, je peux créer du code comme
la source
Tous les programmeurs débutants doivent être obligés d’adhérer à ce principe. Cela les obligerait à réfléchir à la structure de ce qui les occupe, au lieu d’ajouter de plus en plus de code de lignes.
J'examine actuellement une méthode de 550 lignes de code avec de nombreuses instructions if else, et continue et renvoie des éléments entrés dans celle-ci. C'est de la crotte. Le programmeur avait-il seulement été forcé de penser à ce qu'il faisait ...
la source