En programmation orientée objet, il n’existe bien sûr pas de règle exacte sur la longueur maximale d’une méthode, mais j’ai quand même trouvé ces deux citations qui se contredisaient un peu, je voudrais donc connaître votre opinion.
Dans Clean Code: A Handbook of Agile Software Craftsmanship , Robert Martin déclare:
La première règle de fonctions est qu'ils doivent être petits. La deuxième règle de fonctions est qu'ils doivent être plus petits que cela. Les fonctions ne doivent pas comporter 100 lignes. Les fonctions ne devraient pratiquement jamais être longues de 20 lignes.
et il donne un exemple du code Java qu'il voit de Kent Beck:
Chaque fonction de son programme ne comptait que deux, trois, ou quatre lignes. Chacun était transparent. Chacun a raconté une histoire. Et chacun vous a conduit à l'autre dans un ordre convaincant. Voilà comment vos fonctions devraient être courtes!
Cela sonne bien, mais d'autre part, dans Code Complete , Steve McConnell dit quelque chose de très différent:
La routine doit pouvoir croître de manière organique jusqu’à 100-200 lignes, des décennies de données indiquent que les routines d’une telle longueur ne sont plus sujettes aux erreurs, mais plus courtes.
Et il fait référence à une étude selon laquelle les routines de 65 lignes ou plus sont moins coûteuses à développer.
Ainsi, même si les opinions divergent à ce sujet, existe-t-il une meilleure pratique fonctionnelle pour vous?
la source
switch
instruction avec 100case
conditions est plus facile à gérer que 10 niveaux d'if
instructions imbriqués les uns dans les autres.Réponses:
Les fonctions doivent normalement être courtes, entre 5 et 15 lignes est ma "règle empirique" personnelle lors du codage en Java ou en C #. C'est une bonne taille pour plusieurs raisons:
Mais je ne pense pas qu'il soit utile de définir une règle absolue, car il y aura toujours des exceptions / raisons valables pour s'écarter de la règle:
Donc, fondamentalement, utilisez le bon sens , tenez-vous-en à de petites tailles de fonctions dans la plupart des cas, mais ne soyez pas dogmatique à ce sujet si vous avez vraiment une bonne raison de créer une fonction exceptionnellement grande.
la source
Bien que je sois d’accord avec les commentaires des autres quand ils disaient qu’il n’y avait pas de règle absolue concernant le bon numéro de LOC, je parie que si nous regardons en arrière des projets que nous avons examinés dans le passé et identifions chaque fonction ci-dessus, disons 150 lignes de code, je ' Je suppose que nous arriverions à un consensus sur le fait que 9 de ces fonctions sur 10 rompent le PRS (et très probablement le PDP), ont trop de variables locales, trop de flux de contrôle et sont généralement difficiles à lire et à maintenir.
Ainsi, bien que LOC ne soit peut-être pas un indicateur direct d'un code incorrect, il s'agit certainement d'un indicateur indirect décent indiquant que certaines fonctions pourraient être mieux écrites.
Dans mon équipe, je suis tombé dans la position de leader et pour une raison quelconque, les gens semblent m'écouter. Ce que j’ai décidé en général, c’est de dire à l’équipe que bien qu’il n’y ait pas de limite absolue, toute fonction comportant plus de 50 lignes de code devrait au minimum déclencher un drapeau rouge lors de la révision du code, afin que nous puissions y jeter un second regard et le réévaluer. pour la complexité et les violations SRP / OCP. Après ce second regard, nous pourrions le laisser seul ou le changer, mais au moins, cela incite les gens à réfléchir à ces choses.
la source
Je me suis lancé dans un projet qui ne se souciait pas des directives de codage. Quand je regarde dans le code, je trouve parfois des classes avec plus de 6000 lignes de code et moins de 10 méthodes. C'est un scénario d'horreur lorsque vous devez corriger des bugs.
Une règle générale de la taille maximale d'une méthode n'est parfois pas très bonne. J'aime la règle de Robert C. Martin (Oncle Bob): "Les méthodes doivent être petites, plus petites que petites". J'essaie d'utiliser cette règle tout le temps. J'essaie de garder mes méthodes simples et modestes en précisant que ma méthode ne fait qu'une chose et rien de plus.
la source
Il ne s'agit pas du nombre de lignes, mais du SRP. Selon ce principe, votre méthode devrait faire une et une seule chose.
Si votre méthode fait ceci ET ceci ET ceci OU cela => il en fait probablement trop. Essayez de regarder cette méthode et d’analyser: "Ici, je reçois ces données, les trie et obtiens les éléments dont j'ai besoin" et "ici, je traite ces éléments" et "je les combine enfin pour obtenir le résultat". Ces "blocs" doivent être reformulés selon d'autres méthodes.
Si vous suivez simplement SRP, la plupart de vos méthodes seront petites et d’intention claire.
Il n'est pas correct de dire "cette méthode a plus de 20 lignes, donc c'est faux". Cela peut indiquer que quelque chose ne va pas avec cette méthode, pas plus.
Vous pouvez avoir un commutateur de 400 lignes dans une méthode (cela se produit souvent dans les télécommunications), et cela reste une responsabilité unique et tout va bien.
la source
Cela dépend , sérieusement, il n’ya vraiment pas de réponse solide à cette question car le langage avec lequel vous travaillez est important, les lignes 15 à 15 mentionnées dans cette réponse peuvent fonctionner en C # ou en Java, mais cela ne donne pas vous avez beaucoup de travail avec. De même, selon le domaine dans lequel vous travaillez, vous pouvez éventuellement écrire des valeurs de paramétrage de code dans une structure de données volumineuse. Avec certaines structures de données, vous pouvez avoir à définir des dizaines d’éléments. Devriez-vous créer des séparations pour séparer des fonctions simplement parce que votre fonction est longue?
Comme d'autres l'ont noté, la meilleure règle à suivre est qu'une fonction doit être une seule entité logique qui gère une seule tâche. Si vous essayez d'appliquer des règles draconiennes stipulant que les fonctions ne peuvent pas être plus longues que n lignes et que vous réduisez cette valeur à une valeur trop petite, votre code deviendra plus difficile à lire, car les développeurs essaient d'utiliser des astuces sophistiquées pour contourner la règle. De même, si vous le définissez trop haut, ce ne sera pas un problème et peut conduire à un code incorrect si vous êtes paresseux. Votre meilleur choix est simplement de passer en revue les codes pour vous assurer que les fonctions gèrent une tâche unique et en rester là.
la source
Je pense qu'un problème ici est que la longueur d'une fonction ne dit rien sur sa complexité. Les lignes de code (LOC) sont un mauvais instrument pour mesurer quoi que ce soit.
Une méthode ne doit pas être trop complexe, mais il existe des scénarios dans lesquels une méthode longue peut être facilement maintenue. Notez que l'exemple suivant n'indique pas qu'il ne peut pas être divisé en méthodes, mais que ces méthodes ne modifieraient pas la maintenabilité.
Par exemple, un gestionnaire pour les données entrantes peut avoir une instruction switch importante puis un code simple par cas. J'ai un tel code - gérer les données entrantes à partir d'un flux. 70 (!) Gestionnaires codés numériquement. Maintenant, on dira "utiliser des constantes" - oui, sauf que l'API ne les fournit pas et j'aime rester près de "source" ici. Les méthodes? Bien sûr, malheureusement, ils traitent tous de données provenant des mêmes 2 grandes structures. Aucun avantage à les séparer sauf peut-être avoir plus de méthodes (lisibilité). Le code est intrinsèquement peu complexe - un commutateur, en fonction du champ. Ensuite, chaque cas a un bloc qui analyse x éléments de données et les publie. Pas de cauchemar d'entretien. Il y a une condition "répétant" qui détermine si un champ a des données (pField = pFields [x], si pField-> IsSet () {blabla}) - la même chose pour tous les champs ..
Remplacez-la par une routine beaucoup plus petite contenant une boucle imbriquée et un grand nombre d'instructions de commutation réelles et une méthode énorme peut être plus facile à gérer qu'une autre plus petite.
Donc, désolé, LOC n'est pas une bonne mesure pour commencer. Le cas échéant, les points de complexité / décision doivent être utilisés.
la source
Je vais juste ajouter une autre citation.
Il est très improbable que les fonctions qui atteignent 100-200 suivent cette règle
la source
Je suis dans cette raquette folle, d’une manière ou d’une autre, depuis 1970.
Pendant tout ce temps, à deux exceptions près, je n’aurai JAMAIS vu une "routine" bien conçue (méthode, procédure, fonction, sous-programme, etc.) devant BESOIN d’avoir plus d’une page imprimée ( environ 60 lignes) de long. La grande majorité d'entre eux étaient assez courts, de l'ordre de 10 à 20 lignes.
Cependant, j'ai vu BEAUCOUP de code de "flux de conscience", écrit par des personnes qui n'avaient apparemment jamais entendu parler de la modularisation.
Les deux exceptions étaient des cas très particuliers. L'une d'elles est en fait une classe de cas exceptionnels, que je regroupe: de grands automates à états finis, implémentés sous la forme de grandes instructions de commutateur laides, généralement parce qu'il n'y a pas de moyen plus clair de les implémenter. Ces éléments apparaissent généralement dans l'équipement de test automatisé, analysant les journaux de données du périphérique testé.
L'autre était la routine de torpille à photons du jeu STARTRK Matuszek-Reynolds-McGehearty-Cohen, écrite en CDC 6600 Fortran IV. Il devait analyser la ligne de commande, puis simuler le vol de chaque torpille, avec des perturbations, vérifier l’interaction entre la torpille et chaque type de chose qu’elle pouvait frapper, et, au passage, simuler la récursivité pour établir une connectivité à 8 voies sur des chaînes de données. novae de torpiller une étoile qui était à côté d’autres étoiles.
la source
Si je trouve la méthode longue, je pourrais parier que cette méthode n’est pas correctement testée ou que la plupart du temps elle n’a pas du tout de test unitaire. Si vous commencez à utiliser TDD, vous ne construirez jamais de méthodes 100 lignes avec 25 responsabilités différentes et 5 boucles imbriquées. Les tests vous obligent à refactoriser constamment votre désordre et à écrire le code propre à oncle Bob.
la source
Il n'y a pas de règles absolues sur la longueur de la méthode, mais les règles suivantes ont été utiles:
la source
Les auteurs entendent-ils la même chose par "fonction" et par "routine"? Typiquement, quand je dis "fonction", je veux dire un sous-programme / une opération qui retourne une valeur et une "procédure" pour un autre qui ne le fait pas (et dont l'appel devient une seule instruction). Ce n'est pas une distinction commune à travers SE dans le monde réel mais je l'ai vue dans des textes utilisateur.
De toute façon, il n'y a pas de bonne réponse à cela. La préférence pour l’un ou l’autre (s’il ya une préférence du tout) est quelque chose de très différent selon les langues, les projets et les organisations; exactement comme avec toutes les conventions de code.
Le bit que j’ajouterais, c’est que l’assertion entière «les opérations longues ne sont pas plus sujettes aux erreurs que les opérations courtes» n’est pas strictement vraie. En plus du fait que plus de code équivaut à plus d’espace potentiel d’erreurs, il est tout à fait évident que briser le code en segments rendra les erreurs plus faciles à éviter et à localiser. Sinon, il n'y aurait aucune raison de diviser le code en morceaux, sauf la répétition. Mais cela n’est peut-être vrai que si ces segments sont suffisamment documentés pour que vous puissiez déterminer les résultats d’un appel d’opération sans lire ou suivre le code réel (conception par contrat basée sur des spécifications plutôt que par une dépendance concrète entre des zones de code).
En outre, si vous souhaitez que les opérations plus longues fonctionnent correctement, vous pouvez adopter des conventions de code plus strictes pour les prendre en charge. Tossing une instruction de retour au milieu d'une opération peut convenir pour une opération courte, mais dans les opérations plus longues, cela peut créer une grande section de code conditionnelle mais pas évidemment conditionnée à une lecture rapide (juste pour un exemple).
Donc, je penserais que le style qui est le moins susceptible d’être un cauchemar rempli de bogues dépendrait en grande partie des conventions que vous respectez pour le reste de votre code. :)
la source
IMHO, vous ne devriez pas avoir à utiliser la barre de défilement pour lire votre fonction. Dès que vous avez besoin de déplacer la barre de défilement, il vous faut un peu plus de temps pour comprendre le fonctionnement de la fonction.
En conséquence, cela dépend de l'environnement de programmation habituel de votre travail d'équipe (résolution de l'écran, éditeur, taille de la police, etc.). Dans les années 80, c'était 25 lignes et 80 colonnes. Maintenant, sur mon éditeur, j'affiche près de 50 lignes. Le nombre de colonnes que j’affiche n’a pas changé depuis que j’ai divisé mon écran en deux pour afficher deux fichiers à la fois.
En bref, cela dépend de la configuration de vos collègues.
la source
Je pense que la réponse de TomTom est proche de ce que je ressens à ce sujet.
De plus en plus, je me retrouve plutôt dans la complexité cyclomatique que dans les lignes.
Normalement, je ne vise pas plus d'une structure de contrôle par méthode, à l'exception du nombre de boucles nécessaire pour gérer un tableau multidimensionnel.
Je me trouve parfois dans les cas où il y a un changement de ligne parce que, pour une raison quelconque, ce sont généralement des cas où le fractionnement nuit au lieu d'aider.
Notez que je ne compte pas la logique de garde contre cette limite.
la source
Dans OOP, toutes les choses s'opposent et présentent les caractéristiques suivantes:
Lorsque vous respectez ces règles, vos méthodes sont généralement petites, mais il n'existe aucune règle pour les règles petites ou très petites (par exemple, 2 ou 3 lignes). Les avantages d’une petite méthode (petite unité, par exemple méthode ou fonction) sont les suivants:
la source