La longueur de la fonction affecte-t-elle la productivité d'un programmeur? Si tel est le cas, quel est le bon nombre maximal de lignes pour éviter une perte de productivité?
Puisqu'il s'agit d'un sujet très controversé, veuillez sauvegarder la réclamation avec certaines données.
programming-practices
coding-standards
Peter Mortensen
la source
la source
Réponses:
Depuis que je me suis embarqué dans cette folle raquette en 1970, j'ai vu exactement un module qui devait vraiment comporter plus d'une page imprimée (environ 60 lignes). J'ai vu beaucoup de modules plus longs.
D'ailleurs, j'ai écrit des modules plus longs, mais c'étaient généralement de grandes machines à états finis écrites sous forme de grandes instructions switch.
Une partie du problème semble être que les programmeurs n’ont pas appris à modéliser les choses.
Les normes de codage qui maximisent le gaspillage de l’espace vertical semblent également faire partie du problème. (Je n'ai pas encore rencontré un responsable de logiciel qui a lu la " Psychologie de la programmation informatique " de Gerald Weinberg . Weinberg souligne que de nombreuses études ont montré que la compréhension du programmeur est essentiellement limitée à ce que le programmeur peut voir à un instant donné. le programmeur doit faire défiler ou tourner une page, sa compréhension diminue de manière significative: il doit se rappeler et résumer.)
Je reste convaincu que les gains de productivité bien documentés de FORTH, bien documentés, sont dus au système de "bloc" FORTH pour code source: les modules étaient limités à 16 lignes de 64 caractères. Vous pouvez factoriser à l'infini, mais vous ne pouvez en aucun cas écrire une routine de 17 lignes.
la source
Quelle est la bonne taille, vraiment?
Cela dépend de la langue que vous utilisez, mais en général (et à mon goût personnel):
Si c'est plus, alors c'est quelque chose que je dois revenir plus tard et retravailler.
Mais, de manière réaliste , quelle que soit la taille requise pour livrer quelque chose et qu'il est plus logique de la répartir ainsi, il est parfois encore plus facile pour quelqu'un de vérifier avant expédition. (mais reviens quand même plus tard).
(Récemment, mon équipe a lancé un programme sur notre base de code: nous avons trouvé une classe avec 197 méthodes et une autre avec seulement 3 méthodes, mais l’une d’elles était de 600 lignes. Cute game: quel est le pire des 2 maux?)
Maintenant, pour une réponse plus zen ... En général, il est considéré comme une bonne pratique de citer un ou deux grands hommes, alors voici:
Addendum sur les styles de commentaires
En plus de cela, vos fonctions devraient avoir des noms clairs expliquant leur intention. En ce qui concerne les commentaires, généralement, je ne commente pas dans une fonction:
Un bloc de commentaires en haut de chaque fonction (qui nécessite une explication) suffit. Si votre fonction est petite et que les noms de fonction sont suffisamment explicites, vous devez simplement indiquer ce que vous souhaitez réaliser et pourquoi. J'utilise des commentaires en ligne uniquement pour les champs de certaines langues ou lors du démarrage de blocs pour les fonctions qui ne respectent pas les règles de 25 à 35 lignes si l'intention n'est pas claire. J'utilise un commentaire de bloc dans le code lorsqu'une situation exceptionnelle se produit (un bloc catch pour lequel vous n'avez pas besoin ou ne voulez rien faire devrait comporter un commentaire expliquant pourquoi, par exemple).
Pour plus d'informations, consultez ma réponse sur Style et les recommandations du code de commentaire.
la source
tt
pour les générer, mais parfois vous êtes bloqué avec une fonction de cul long (ou une fonction de cul longue) qui ne fait vraiment rien d'intéressant de toute façon alors ce n'est pas un vrai problème.Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3);
il est clair que tout est identique. (Notez que ceci est juste un exemple; ce genre de fonction apparaît de temps en temps)À mon avis, chaque fonction devrait être aussi petite que possible. Chaque fonction ne doit faire qu’une chose et le faire bien. Cela ne répond pas vraiment à la question de longueur maximale, mais c’est plus mon sentiment sur la durée des fonctions.
Pour utiliser les mots de Oncle Bob, "Extrait jusqu'à ce que tu ne puisses plus en extraire. Extrait jusqu'à ce que tu tombes."
la source
Quelle devrait être la hauteur maximale d'un bâtiment? Cela dépend de l'emplacement de la construction ou de la hauteur souhaitée.
Vous pouvez obtenir différentes réponses de personnes différentes venant de différentes villes.
Certaines fonctions de script et certains gestionnaires d’interruptions du noyau sont très longs.
la source
Une méthode qui fonctionne pour moi est la suivante: puis-je avoir une partie d'une fonction plus longue donner un nom qui a du sens. Je pense que la longueur d'une méthode n'est pas aussi importante qu'une bonne dénomination. La méthode devrait faire ce que son nom l'indique, ni plus ni moins. Et vous devriez pouvoir donner un bon nom. Si vous ne pouvez pas nommer bonne votre méthode, le code n'est probablement pas bien mis ensemble.
la source
Tant qu'il faut faire ce qu'il faut faire, mais pas plus longtemps.
la source
Je pense qu'il y a un compromis. Si vous avez beaucoup de méthodes courtes, il est souvent plus difficile de les déboguer qu’une méthode longue. Si vous devez parcourir l'éditeur 20 ou 30 fois pour tracer un appel de méthode, il sera difficile de tout garder dans votre tête. En attendant, s’il existe une méthode claire et bien écrite, même s’il s’agit de 100 lignes, il est souvent plus facile de la garder à l’esprit.
La vraie question est de savoir pourquoi les éléments devraient être dans des méthodes différentes, et la réponse donnée ci-dessus est la réutilisation de code. Si vous ne réutilisez pas le code (ou si vous ne le savez pas), il peut être judicieux de le laisser dans une méthode simple, facile à suivre, puis, si vous devez le réutiliser, séparez les parties qui ont besoin d'être réutilisées. en utilisant des méthodes plus petites.
En réalité, une bonne conception de méthode consiste à créer des méthodes fonctionnellement cohérentes (essentiellement, elles ne font qu'une chose). La longueur des méthodes n'a pas d'importance. Si une fonction fait une chose bien définie et vaut 1000 lignes, c'est une bonne méthode. Si une fonction fait 3 ou 4 choses et ne compte que 15 lignes, alors c'est une mauvaise méthode ...
la source
Je trouve plus facile de garder une trace de ce que je fais si je peux voir toute la fonction en une fois. Alors voici comment je préfère écrire des fonctions:
J'écris rarement des fonctions plus longtemps que ça. La plupart sont des déclarations de commutateur géantes C / C ++.
la source
Pour moi, une fonction est une longueur quelconque. La plupart du temps, je le divise lorsque je vais réutiliser du code.
Fondamentalement, je vais m'en tenir au principe 'forte cohésion, couplage faible' et il n'y a pas de contrainte de longueur.
la source
La question devrait être combien de choses une fonction devrait faire. Et généralement, il est rare que vous ayez besoin de 100 lignes pour faire "une" chose. Encore une fois, cela dépend du niveau auquel vous regardez le code: Est-ce que le hachage d'un mot de passe est une chose? Ou bien le hachage et la sauvegarde du mot de passe sont-ils une chose?
Je dirais, commencez par enregistrer le mot de passe en une fonction. Lorsque vous sentez que le hachage est différent et que vous refactorisez le code. Je ne suis en aucun cas un programmeur expert, mais à mon humble avis, l’idée même des fonctions est modeste: plus vos fonctions sont atomiques, plus les chances de réutilisation du code sont élevées, sans avoir à effectuer le même changement à plusieurs endroits. , etc.
J'ai vu des procédures stockées SQL qui exécutent plus de 1000 lignes. Le nombre de lignes de procédures stockées est-il également inférieur à 50? Je ne sais pas, mais ça rend la lecture du code, bordel. Non seulement vous devez continuer à faire défiler l'écran, vous devez également attribuer à quelques lignes de code un nom tel que "ceci ne se valide pas1", "ceci se met à jour dans la base de données", etc. - un travail que le programmeur aurait dû effectuer.
la source
De la complexité cyclomatique (Wikipedia):
Je vous recommande de garder ce nombre inférieur à 10 dans une seule méthode. S'il arrive à 10, alors il est temps de re-factoriser.
Il existe des outils permettant d’évaluer votre code et de vous donner un numéro de complexité cyclomatique.
Vous devez vous efforcer d'intégrer ces outils dans votre pipeline de construction.
Ne poursuivez pas littéralement une méthode de taille, mais essayez de regarder sa complexité et ses responsabilités. S'il a plus d'une responsabilité, alors c'est probablement une bonne idée de re-factoriser. Si sa complexité cyclomatique augmente, alors il est probablement temps de re-factoriser.
Je suis à peu près certain qu'il existe d'autres outils qui vous donnent des retours similaires, mais je n'ai pas encore eu l'occasion de me renseigner à ce sujet.
la source
En règle générale, j'essaie de garder mes méthodes / fonctions à ce qui convient à l'écran d'un moniteur 1680x1050. Si cela ne convient pas, utilisez des méthodes / fonctions d'assistance pour répartir la tâche.
Cela facilite la lisibilité à la fois sur l’écran et sur le papier.
la source
Je ne mets pas de limite stricte à quoi que ce soit car certaines fonctions implémentent des algorithmes intrinsèquement complexes et toute tentative de les raccourcir rendrait les interactions entre les nouvelles fonctions plus courtes si compliquées que le résultat final ne réduirait pas la simplicité. Je ne crois pas non plus que l'idée qu'une fonction ne doive faire que "une chose" soit un bon guide, car "une chose" à un niveau d'abstraction élevé peut être "beaucoup de choses" à un niveau inférieur.
Pour moi, une fonction est définitivement trop longue si sa longueur provoque des violations subtiles de DRY à l'heure actuelle, et l'extraction d'une partie de la fonction dans une nouvelle fonction ou classe pourrait résoudre le problème. Une fonction peut être trop longue si ce n’est pas le cas, mais une fonction ou une classe pourrait facilement être extraite, ce qui rendrait le code plus modulaire d’une manière qui pourrait être utile face à des changements prévisibles.
la source
Assez court pour être optimisé correctement
Les méthodes doivent être assez courtes pour faire exactement une chose. La raison en est simple: votre code peut donc être correctement optimisé.
Dans un langage JIT-ted tel que Java ou C #, il est important que vos méthodes soient simples afin que le compilateur JIT puisse produire du code rapidement. Les méthodes plus longues et plus compliquées nécessitent naturellement plus de temps JIT. De plus, les compilateurs JIT n'offrent qu'une poignée d'optimisations et seules les méthodes les plus simples en bénéficient. Ce fait a même été évoqué dans le document Effective C # de Bill Wagner .
Dans un langage de niveau inférieur, tel que C ou C ++, il est également important de disposer de méthodes courtes (une douzaine de lignes environ), car cela permet de réduire le besoin de stocker des variables locales dans la RAM plutôt que dans un registre. (Aka 'Register Spilling'.) Notez cependant que dans ce cas non géré, le coût relatif de chaque appel de fonction peut être assez élevé.
Et même dans un langage dynamique, comme Ruby ou Python, l'utilisation de méthodes courtes facilite également l'optimisation du compilateur. Dans un langage dynamique, plus une fonctionnalité est "dynamique", plus il est difficile de l'optimiser. Par exemple, une méthode longue qui prend un X et peut renvoyer un Int, Float ou String s'exécutera probablement beaucoup plus lentement que trois méthodes distinctes qui ne renvoient chacune qu'un seul type. En effet, si le compilateur sait exactement quel type la fonction retournera, il pourra également optimiser le site d’appel de la fonction. (Par exemple, ne pas vérifier les conversions de type.)
la source
Cela dépend beaucoup du contenu du code.
J'ai vu une routine de mille lignes avec laquelle je n'ai eu aucun problème. C'était une déclaration de commutateur énorme, aucune option ne dépassait une douzaine de lignes et la seule structure de contrôle de toutes les options était une boucle unique. Ces jours-ci, il aurait été écrit avec des objets, mais ce n'était pas une option à l'époque.
Je regarde également 120 lignes dans un commutateur devant moi. Aucune affaire ne dépasse 3 lignes - une garde, une affectation et la pause. C'est l'analyse d'un fichier texte, les objets ne sont pas une possibilité. Toute alternative serait plus difficile à lire.
la source
La plupart des compilateurs ne se préoccupent pas de la longueur d'une fonction. Une fonction doit être fonctionnelle, mais facile à comprendre, à modifier et à réutiliser pour l’être humain. Choisissez la longueur qui vous convient le mieux.
la source
Ma règle générale est qu'une fonction doit tenir à l'écran. J'ai trouvé que trois cas tendent à violer ceci:
1) Fonctions de répartition. Dans l'ancien temps, ils étaient courants, mais la plupart d'entre eux sont remplacés par un héritage d'objet ces jours-ci. Cependant, les objets ne fonctionnent que dans votre programme et vous verrez donc toujours des fonctions de répartition occasionnelles lorsque vous manipulerez des données provenant d'autres sources.
2) Fonctions qui accomplissent toute une série d’étapes pour atteindre un objectif et où les étapes manquent d’une bonne subdivision. Vous vous retrouvez avec une fonction qui appelle simplement une longue liste d'autres fonctions dans l'ordre.
3) Comme # 2 mais où les étapes individuelles sont si petites qu’elles sont simplement alignées au lieu d’être appelées séparément.
la source
Peut-être que la longueur de la fonction n'est pas une bonne métrique. Nous essayons d'utiliser la complexité cyclomatique , sur les méthodes également, et l'une des futures règles d'archivage du contrôle de source selon laquelle la complexité cyclomatique sur les classes et les méthodes doit être inférieure à X.
Pour les méthodes, X est défini sur 30, ce qui est assez serré.
la source