A quel point / plage un fichier de code est-il trop gros?


36

Je trouve beaucoup de fichiers de 2 à 3 000 lignes et je ne pense pas qu'ils devraient être aussi gros.

Quel est le bon critère pour appeler objectivement un fichier de code source "trop ​​gros"?, Existe-t-il un nombre maximal de lignes qu'un fichier de code source devrait avoir?


Votre pair vous dit après avoir examiné le code. "Vous ne pouvez pas le déterminer vous-même, car vous en savez plus que l'auteur ne le dit pas lui-même sur le code. Un ordinateur ne peut pas vous le dire, pour les mêmes raisons qu'il ne peut pas dire si un tableau est un art ou non. Par conséquent, vous avez besoin d'un autre humain de maintenir le logiciel - pour regarder ce que vous avez écrit et donner son opinion ... "
gnat

Certains compilateurs avaient des limites étranges sur la taille du code source: longueur de ligne maximale ou nombre maximal de lignes. Lorsque le compilateur se plaint, il s'agit d'un indicateur objectif indiquant que le code est trop volumineux (ou qu'il est temps de procéder à la mise à niveau).
mouviciel

2
Fractionner autant que possible, mais sans casser l'intégrité des fichiers. Chaque fichier (ou paire de fichiers en-tête / source) doit toujours être un ensemble arrondi, indépendant de la mise en œuvre interne des autres fichiers. Si cela signifie que certains fichiers seront volumineux car ils implémenteront quelque chose de complexe, qu’il en soit ainsi.
Ambroz Bizjak

Notez que la complexité ne concerne pas seulement les chiffres, mais également la structure. Par exemple, je voudrais dire que le zen python "flat is better is nested": une liste plate de 100 cas est plus simple qu'une hiérarchie (vous ne vous souviendrez pas des 100 cas mais vous vous souviendrez facilement qu'il y a 100 alternatives) . Et une hiérarchie "régulière" où les branches ont la même structure que leurs frères et soeurs sont plus simples qu'une hiérarchie avec une sous-structure irrégulière.
Juillet

"Est-ce que c'est le code source?" "Non, c'est le makefile, le code source est dans les camions qui suivent".
McKenzm

Réponses:


26

En tant que modèle idéal, j'utilise les critères suivants (avec une logique similaire à celle suggérée par Martin Beckett, à savoir de penser en termes de structure logique et non en termes de lignes de code):

Règle 1

Une classe par fichier (en C ++: une classe -> un en-tête et un fichier d'implémentation).

Règle 2

Sept sont considérés comme le nombre d'éléments que notre cerveau peut observer en même temps sans se confondre. Au-dessus de 7, il nous est difficile de garder une vue d'ensemble de ce que nous voyons. Par conséquent: chaque classe ne devrait pas avoir plus de 7-10 méthodes. Une classe qui a plus de 10 méthodes est probablement trop complexe et vous devriez essayer de la scinder. La scission est une méthode très efficace car chaque fois que vous divisez une classe, vous réduisez la complexité de chaque classe au moins d'un facteur 2.

Règle 3

Un corps de méthode qui ne tient pas dans un ou deux écrans est trop grand (je suppose qu'une fenêtre écran / éditeur a environ 50 lignes). Idéalement, vous pouvez voir toute la méthode dans une seule fenêtre. Si ce n'est pas le cas, il vous suffit de faire défiler un peu, sans oublier la partie de la méthode qui est masquée. Ainsi, si vous devez faire défiler plusieurs écrans vers le haut ou le bas pour lire tout le corps de la méthode, celle-ci est probablement trop volumineuse et vous pouvez facilement perdre la vue d'ensemble.

Là encore, le fractionnement de méthodes à l'aide de méthodes d'aide privées peut réduire très rapidement la complexité de la méthode (la complexité est au moins divisée par deux). Si vous introduisez trop de méthodes d'aide privées, vous pouvez créer une classe distincte pour les collecter (si vous avez plus de méthodes privées que de méthodes publiques, une deuxième classe se cache peut-être dans votre classe principale).

En rassemblant ces estimations très approximatives:

  • Au plus une classe par fichier source.
  • Au plus 10 méthodes publiques par classe.
  • Au maximum 10 méthodes privées par classe.
  • Au plus 100 lignes par méthode.

Ainsi, un fichier source de plus de 2000 lignes est probablement trop volumineux et commence à être trop compliqué.

C'est vraiment une estimation très approximative et je ne suis pas systématiquement ces critères (surtout parce qu'il n'y a pas toujours assez de temps pour refactoriser correctement). En outre, comme l'a suggéré Martin Beckett, il existe des situations dans lesquelles une classe est un vaste ensemble de méthodes et il n'est pas logique de les diviser de manière artificielle simplement pour réduire la taille de la classe.

Quoi qu’il en soit, selon mon expérience, un fichier commence à devenir illisible lorsque l’un des paramètres ci-dessus n’est pas respecté (par exemple, un corps de méthode de 300 lignes couvrant six écrans ou un fichier source contenant 5 000 lignes de code).


1
Je m'efforcerais également de disposer de méthodes ne dépassant pas 10 lignes ... aide à la lisibilité / à la compréhension de ce que fait la méthode et réduit la complexité pouvant survenir avec les grandes méthodes ...
Zack Macomber

4
Rule2 est absurde si vous la suivez jusqu'à sa conclusion. Vous ne devez pas avoir plus de 7 fichiers dans un répertoire. Vous devez donc garder vos fichiers volumineux afin d'éviter toute confusion entre les dizaines, voire les centaines de fichiers de votre projet. De même, une structure de répertoire profondément imbriquée est trop déroutante, il est donc préférable de conserver quelques fichiers volumineux dans un seul répertoire plutôt que de tout disperser.
Hasen

1
Je suis désolé, cette réponse est basée sur des métriques totalement arbitraires. Les "7 éléments" sont clairement des conneries, sinon vous ne pourriez pas utiliser l'alphabet. La taille de l'objet doit être basée sur la séparation des préoccupations, la responsabilité unique, le principe de cohésion élevée, le couplage faible et les principes similaires, et non sur des nombres arbitraires.
JacquesB

1
@JacquesB Les 7 éléments sont généralement indicatifs de 7 informations non liées. Si votre cerveau peut associer ou regrouper des informations, il s’agit en réalité d’une information qui peut en amener plus si vous essayez de vous en rappeler (en fait, "alphabet" est un symbole, pas les 26 lettres). Un meilleur exemple serait d’essayer de vous rappeler un numéro à 7 chiffres qui vous est dit par téléphone sans avoir un stylo et du papier à disposition. Les méthodes ne sont clairement pas des nombres arbitraires, mais si ces méthodes sont pertinentes par rapport à ce que vous codez, vous pouvez vous attendre après 7, vous devrez les chercher avant de pouvoir vous rappeler correctement.
Neil

3
@Neil: Si les méthodes d'une classe sont des informations aléatoires non liées, le problème de conception de votre classe est plus important que le nombre de méthodes.
JacquesB

33

Non, pas en termes de lignes de code. Le pilote doit être un groupement logique. Il ne devrait certainement pas y avoir plusieurs classes dans un seul fichier volumineux, par exemple

Si vous avez une classe qui possède légitimement quelques centaines de méthodes (ce qui n’est pas impossible dans le cas de la modélisation 3D), il serait beaucoup moins pratique de la scinder en fichiers arbitraires. Nous avions l'habitude de faire cela lorsque la mémoire était plus rare et les processeurs plus lents - et c'était une douleur, de rechercher constamment la définition de la fonction.


2
Une classe avec des centaines de méthodes ne serait-elle pas un symptôme d'envie de classe, de manque de cohésion, de conception médiocre, de violation du principe de responsabilité unique, etc.?
Tulains Córdova

2
@ user1598390: généralement, mais pas toujours.
Whatsisname

4
@ user1598390 - dans la modélisation gis / 3d par exemple, vous pouvez effectuer un grand nombre d'opérations, puis les surcharger pour 2d, 3d, 4d, signal 3d +, puis float / double / integer, etc. beaucoup d'opérations sont souvent meilleures qu'une belle hiérarchie de classe
Martin Beckett

2
@ tp1 - et vous utilisez une petite police pour ne pas prendre autant de place?
Martin Beckett

2
@ tp1 Mec, je suis désolé, je ne veux vraiment pas manquer de respect, mais je suis désolé pour quiconque travaille avec vous. Si vous avez 1 200 classes, utilisez une convention de répertoire; si vous avez trop de répertoires, divisez-les en modules / bibliothèques indépendants.
dukeofgaming

8

Lorsque le code qu'il contient devient inaccessible. C'est-à-dire: vous ne pouvez pas simplement vérifier en regardant le code si la méthode / classe / fonction que vous recherchez (et que vous devez éditer / déboguer) est présente ou non, et si oui, où il se trouve.

Votre choix et vos fonctionnalités IDE / Editor influenceront cependant la quantification réelle de cette limite supérieure. Code pliage , fonction / méthode d' inscription, et recherche va reporter le moment ce scénario de développement présente.

Mais quand c'est le cas, il est temps de le scinder.


2

Voici une autre vue: vous demandez comment limiter la taille du fichier. Mon avis est qu’il existe de nombreux facteurs qui rendent les gros fichiers de code très problématiques. Parfois, le fichier de code est volumineux mais son contenu est bien structuré en grappes et extrêmement propre, de sorte que sa taille ne pose pas de problème majeur. J'ai vu beaucoup de fichiers très lisibles malgré un LOC élevé.

Au lieu d'exploiter la métrique LOC, je préférerais utiliser les données d'historique pour comprendre à quelle fréquence le code est cassé dans ces fichiers volumineux. Habituellement, la raison en est que les développeurs n’ont pas le temps de patienter pour vérifier les autres emplacements pertinents dans le même fichier et pour effectuer le changement avec une mentalité de "solution miracle" sans une compréhension suffisante.

Le plus grand danger est la présence de code copier-coller. Le codage par copier-coller accélère naturellement aussi la croissance du LOC. Je pense qu’éliminer le copier-coller est encore plus important que de garder LOC au-dessous d’un nombre magique. En plus du copier-coller pur, il existe également un second danger dans les gros fichiers: le chevauchement des fonctionnalités. Plus le fichier est volumineux, plus vous risquez de réimplémenter un extrait qui se trouve déjà dans une autre section du même fichier.

Donc, tant que rapport de bug fix (rapport de commits de correction de bug à tous les commits) est faible pour les fichiers plus volumineux, la situation est tolérable. Essayez git log-le et parcourez le nombre de commits liés à des erreurs. Ou utilisez un outil capable de l’analyser et de le visualiser automatiquement, par exemple Softagram .


-1

Considérez ceci Metaphor. En ce qui concerne la longueur du code, je pense que nous devrions considérer les points suivants:

The Cat in The Hat (50 pp.)

et

Lord of The Rings (1,178 pp.)

Il n'y a rien de mal avec Lord of the Rings. C'est un livre fabuleux. The Cat in the HatC'est aussi un bon livre. Les deux peuvent être compris par un enfant de 5 ans, mais un seul convient mieux en raison du contenu.

Pour moi, écrire du code devrait avoir du sens pour un enfant de 5 ans chaque fois que nous le pouvons. Cyclomatic ComplexityC’est un concept important que les développeurs doivent peut-être prendre en compte lorsqu’ils génèrent du code. Utiliser et créer des bibliothèques pour améliorer autant que possible les fonctionnalités et la réutilisation du code. De cette façon, notre code peut parler plus de volumes que ce que nous voyons écrit.

La plupart d'entre nous n'écrivons pas de code d'assemblage . Mais la racine de notre code est l’assemblage. La recherche dans l'assemblage 10000 lignes est plus difficile que 10000 lignes de python, si elle est effectuée correctement.

Mais certains travaux nécessitent l’écriture de 500 à 1000 lignes. Notre objectif avec le code devrait être d'écrire 300 lignes de code propre.

En tant que développeurs, nous voulons écrire "Le Seigneur des Anneaux". Jusqu'à ce que nous obtenions un bug et souhaitions écrire "Cat in the Hat". Ne faites pas du codage une mesure de l'ego. Faites que les choses fonctionnent de manière simple.

Les développeurs ne veulent pas documenter le code (j'aime le code documenté personnellement, je ne suis pas si égoïste). Donc n'écrivez pas de code que vous seul pouvez comprendre / lire. Écrivez le Cat in the Hatcode.

Nous savons tous que vous êtes JRR Tolken (dans votre tête). N'oubliez pas que vous n'aurez rien à prouver avec un code sans bug.

Une autre raison de la métaphore.

Ne pas exagérer le lecteur répartir la richesse. Si vous travaillez avec un groupe de personnes et que toutes doivent modifier le même fichier volumineux, vous allez probablement vous mettre à gitfondre.

Tout le monde aime rebaser.

-> dit personne jamais!

TL; DR Concentrez-vous sur la lisibilité. Répartissez votre code et votre assistant sur plusieurs lignes et fichiers autant que vous le pouvez. Ne jetez pas 8 ou 9 classes dans un seul fichier, cela rend le code difficile à lire et à gérer. Si vous avez un code de condition ou une boucle volumineux, envisagez de les remplacer par Lambdas si le langage le prend en charge. Les fonctions utilitaires doivent être considérées comme une excellente solution pour améliorer la lisibilité du code. Évitez les nids lourds.


Pas un vote négatif, mais votre analogie est un peu perdue pour moi. Voulez-vous dire qu'il vaut mieux étaler votre code sur plusieurs lignes et avoir moins de mots sur chaque ligne?
Fourrage

Répartissez le code et l'aide sur plusieurs lignes et fichiers autant que vous le pouvez. Concentrez-vous sur la lisibilité. Ne jetez pas 8 ou 9 classes dans un seul fichier. Cela rend le code difficile à lire et à gérer. Si vous avez un code de condition important ou des boucles. Transformez-les en utilitaires. Évitez les nids lourds. S'il vous plaît laissez-moi savoir si cela permet de l'expliquer.
GetBackerZ

Peut-être devriez-vous insérer cela dans votre réponse, cela clarifierait ce que vous voulez dire.
Fourrage

J’ai utilisé le script de Jackie Brown comme référence pour les programmes z / OS COBOL modulaires. Vous savez, pour un cocktail
festif

"donner un sens à un 5 ans chaque fois que nous pouvons." - pour les problèmes réels qui paient les factures, cela est rarement possible et vise la mauvaise chose
whatsisname
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.