web-dev-qa-db-fra.com

Comment sauriez-vous si vous avez écrit du code lisible et facilement maintenable?

Comment savoir si le code que l'on a créé est facilement lisible, compréhensible et maintenable? Bien sûr, du point de vue de l'auteur, le code est lisible et maintenable, car l'auteur l'a écrit et édité, pour commencer. Cependant, il doit exister une norme objective et quantifiable permettant à notre profession de mesurer le code.

Ces objectifs sont atteints lorsque l'on peut faire ce qui suit avec le code sans les conseils d'experts de l'auteur original:

  • Il est possible de lire le code et de comprendre à un niveau de base le flux de la logique.

  • Il est possible de comprendre à un niveau plus profond ce que fait le code pour inclure les entrées, les sorties et les algorithmes.

  • D'autres développeurs peuvent apporter des modifications significatives au code d'origine telles que des corrections de bogues ou une refactorisation.

  • On peut écrire du nouveau code tel qu'une classe ou un module qui exploite le code d'origine.

Comment quantifier ou mesurer la qualité du code afin de le savoir lisible, compréhensible et maintenable?

351
KyelJmD

Votre pair vous le dit après avoir examiné le code.

Vous ne pouvez pas le déterminer vous-même car en tant qu'auteur, vous en savez plus que le code ne le dit lui-même. Un ordinateur ne peut pas vous dire, pour les mêmes raisons qu'il ne peut pas dire si une peinture est de l'art ou non. Par conséquent, vous avez besoin d'un autre humain - capable de maintenir le logiciel - pour regarder ce que vous avez écrit et donner son avis. Le nom officiel dudit processus est examen par les pairs .

387
user1249

Parfois, la meilleure façon de le savoir est de revenir au code que vous avez écrit il y a six mois et d'essayer de comprendre ce pour quoi il a été écrit.

Si vous le comprenez rapidement - c'est lisible.

230
Alex In Paris

C'est:

  1. maintenable si vous pouvez le maintenir .
  2. facilement maintenable si quelqu'un d'autre peut le maintenir sans vous demander de l'aide
  3. lisible si quelqu'un d'autre , en le lisant, correctement comprend le design, disposition et intention

Le vrai test pour 1. est (comme Alex à Paris et quant_dev disons) que vous pouvez le récupérer après quelques mois en faisant autre chose.

Le test pour 2. et 3. est que quelqu'un d'autre peut le récupérer et trouver comment étendre ou corriger votre code tout en suivant le grain de votre conception. S'ils ne peuvent pas comprendre la conception, la relation avec l'espace du problème ou la manière dont votre code est destiné , ils pirateront un solution à travers le grain à la place.

Il y a des règles d'or, des principes (c.-à-d. Des règles d'or, quelqu'un a bien écrit et a donné un nom) et toutes sortes de suggestions qui peuvent vous conduire dans la bonne direction, ou loin des pièges courants. Cependant, aucun d'eux ne garantit les qualités que vous demandez.

94
Useless

Si votre code suit les principes SOLIDE et SEC et a un bon ensemble de tests unitaires autour d'elle, il est probablement maintenable.

Est-il lisible? Lis le. Les noms de méthode et de variable ont-ils un sens? Pouvez-vous suivre la logique du programme sans problème? Si la réponse est oui, alors le code est lisible.

31
Oded

Lecture Comment écrire du code non maintenable - Assurer un travail à vie par Roedy Green, rire et apprendre.

... comment écrire du code si difficile à maintenir, que les personnes qui vous suivront mettront des années à effectuer les changements les plus simples. De plus, si vous suivez religieusement toutes ces règles, vous vous garantissez même toute une vie d'emploi, car personne d'autre que vous n'a un espoir d'enfer de maintenir le code ...

L'essai vous donne de nombreux exemples sur la façon d'écrire du mauvais code, en utilisant de nombreux exemples amusants. Il continue d'expliquer comment utiliser l'orthographe créative , la réutilisation des noms , la technique très appréciée de Réutilisation des noms globaux comme privé .

De manière humoristique, l'essai vous apprend à éviter tous les exemples de code illisible et non maintenable.

En fait, j'ai eu du mal à croire que quiconque écrirait du code avec des similitudes avec les exemples dans le texte. C'est à ce moment-là que je venais de sortir de l'école. Mais, après avoir travaillé pendant quelques années, je vois tous les jours le code du texte…

26
iikkoo

Malgré son apparence, il existe des mesures assez objectives que vous pouvez envisager. Des livres comme Normes de codage C++ , Refactoring , et Clean Code ont de longues listes de critères pour juger votre code, en regardant des choses comme des noms significatifs, tailles de fonctions, principes comme le couplage et la cohésion, conception d'objets, tests unitaires, raffinements successifs, etc.

La liste est trop longue pour pouvoir faire l'objet d'une liste de contrôle, mais vous lisez le livre et choisissez quelques éléments clés sur lesquels travailler, puis après plusieurs mois, relisez-le pour vous améliorer davantage.

22
Karl Bielefeldt

La preuve est dans le pudding. Regardez ce qui se passe après l'avoir remis à une personne raisonnablement compétente. S'ils n'ont pas besoin de poser beaucoup de questions concernant la difficulté du code, vous avez fait du bon travail.

Ce fut une première leçon de ma carrière. Un mentor a dit: "Documentez tout, afin de pouvoir échapper au programme plus tard. Si vous ne prévoyez pas de questions lorsque les réponses vous reviendront à l'esprit, vous devrez les comprendre lorsqu'elles ne le sont pas."

19
MathAttack

J'ai lu toutes les réponses et j'ai remarqué que personne n'a mentionné la complexité du code.

Il existe une étroite corrélation entre la complexité du code et la lisibilité/maintenabilité. Il existe de nombreux algorithmes de notation de la complexité du code, mais je vais juste parler du fonctionnement du score de complexité McCabe.

Fondamentalement, la notation McCabe lit votre code et calcule le nombre de "chemins" uniques qui le traversent. Si vous utilisez McCabe comme numérateur et des lignes de code comme dénominateur, vous obtenez également une assez bonne approximation de la "lisibilité".

Si vous avez 10 lignes de code et qu'il y a 300 chemins à travers ce code, c'est un code assez difficile à maintenir (difficile à changer en toute sécurité et facilement), et ce n'est probablement pas très lisible. Inversement, si vous avez 300 lignes de code, mais qu'il n'y a qu'un seul chemin (il n'a pas de conditions), il est à la fois lisible et facilement maintenable.

Mais là où McCabe tombe, c'est dans ce dernier exemple. Si j'ai 300 lignes de code sans conditions, il y a de fortes chances que j'aie fait une "réutilisation copier/coller", et évidemment ce n'est pas une bonne chose non plus. Il existe donc des mesures à l'échelle du système que vous appliquez en plus de McCabe - comme la détection de code en double ou presque en double.

18
Calphool

Comment savoir si le code qu'il a créé est facilement maintenable et lisible?

Vous pouvez repérer du code facile à entretenir et lisible en recherchant ces propriétés:

  1. Les objets, méthodes et/ou fonctions font toujours une chose.
  2. Les méthodes et/ou fonctions sont concises (comme dans "brèves mais complètes").
  3. Les objets, méthodes et/ou fonctions font essentiellement ce que vous pensez qu'ils sont censés faire en fonction de leurs noms.
  4. Le code destiné à être réutilisé est en fait réutilisable.
  5. Enfin et surtout, si vous pouvez immédiatement tester le code à l'unité, vous avez probablement écrit du code modulaire à responsabilité unique à tout le moins.

Comment saurions-nous si nous avons écrit du code assez désordonné et non gérable? Y a-t-il des constructions ou des directives pour savoir si nous avons développé un logiciel en désordre?

  1. Si vous lisez une méthode et que vous ne savez pas quelle était l'intention, celle-ci est au mieux inélégante et probablement impossible à maintenir au pire.
  2. Si cela ne semble pas simple, ce n'est probablement pas simple et c'est un signe de code incontrôlable ou de code qui deviendra bientôt incontrôlable.
  3. S'il y a un manque de symétrie (cohérence) à travers la base de code, vous regardez probablement du code non maintenable.
8
Wil Moore III

Dans un seul mot, Expérience.

Pour commencer, vous devez avoir mis le travail au sol, donc je ne peux pas recommander plus fortement que les programmeurs prennent le temps de lire des livres tels que Refactoring , qui fournira certains des outils les plus essentiels dans un arsenal de programmeurs qui améliorera votre capacité à maintenir le code, et Clean Code qui a été écrit par certains des talents les plus reconnaissables dans notre domaine, et qui décrit presque tout ce que vous devez comprendre pour pour vous assurer que votre code est propre et lisible.

Aucune lecture n'est cependant un substitut à une expérience durement gagnée. Vous devez vraiment avoir travaillé avec le code pendant un certain temps afin d'apprécier pleinement la différence que l'attention à la qualité du code peut faire. En éprouvant le plaisir de travailler avec du code propre et bien factorisé, ainsi que la douleur de travailler avec du code spaghetti, vous apprenez à mieux comprendre ce que les auteurs de ces livres essayaient vraiment de vous enseigner, mais vous le faites dans un contexte plus large du vrai code de production en direct, où la qualité de ce que vous faites est vraiment importante et affecte votre capacité à travailler facilement avec votre code au quotidien.

Il est également utile d'avoir un bon mentor ou un pair ayant l'expérience pour confirmer que vous mettez l'effort d'écrire du code à un niveau élevé. Ce n'est qu'une des raisons pour lesquelles les revues de code peuvent être si utiles. L'utilisation d'outils de vérification et de mise en forme de code peut également être une aide très utile pour s'assurer que vous gardez les choses propres. Cependant, rien ne se compare à l'expérience acquise au fil des années d'écriture de logiciels, de sorte que vous vous retrouvez automatiquement à écrire du code propre, lisible et structuré simplement pour faciliter la maintenance, et tout cela parce que vous avez pris l'habitude d'appliquer les meilleures pratiques pour longue.

8
S.Robins

Un point que je partagerais est que si le code est construit en "modules", et quand je dis que je veux dire que vous pouvez changer une chose dans un module et le faire fonctionner facilement avec l'ensemble. Il élimine les effets entre des choses indépendantes. Aussi:

  • Le code est facile à réutiliser
  • Votre code est flexible (cela est lié à la construction de modules)
  • SEC - Ne vous répétez pas

Je recommande fortement la lecture du programmeur pragmatique.

8
jket

Quelques tests/indicateurs:

  • Désactivez l'IDE. Pouvez-vous toujours lire votre propre code? Quand il y a un bug, est-il assez facile de le tracer à la main et de déterminer dans quelle classe vous aurez besoin d'un point d'arrêt pour comprendre où est le problème? Ou lorsque vous utilisez le IDE ne vous embêtez-vous pas et ne faites-vous pas un pas dès le début?

  • Le débogage devient souvent un jeu de wack-a-mole où la correction d'un bug en crée 2+ de plus.

  • Du déclenchement déclencheur à quelque chose d'utile qui se passe réellement, combien d'appels de méthode faut-il? Combien de méthodes transmettent exactement les mêmes ou la plupart des mêmes paramètres exacts à un autre appel de méthode?

  • Combien de fichiers devez-vous ouvrir pour simplement ajouter une nouvelle méthode simple à une classe?

  • Pensez aux modèles et aux pratiques que vous avez adoptés. L'avez-vous fait parce qu'ils étaient parfaitement logiques ou parce que quelqu'un vous a convaincu que "c'est la seule façon de le faire?" ou parce que vous le vouliez sur votre CV ou parce qu'un développeur rockstar l'a dit.

8
Erik Reppen

Sans être puritain: préférez le style fonctionnel. De nos jours, la plupart des langues (.NET, Ruby, Python, Javascript, etc.) le prennent en charge et en font la promotion (par exemple LINQ, underscorejs).

Il est extrêmement facile à lire.

var recentTopCustomers = OrderList
    .Where(o => o.Date >= DateTime.Now.AddDays(-5))
    .Where(o => o.Amount > 1000)
    .OrderBy(o => -o.Amount)
    .Take(10)
    .Select(o => o.Customer);

Il oblige chaque nœud à avoir une intention unique et ciblée prêtant à la clarté de l'objectif. Et parce que chaque tâche discrète est isolée, il est trivial de se connecter et de réorganiser les nœuds (opérations) à différentes fins. Cela facilite la maintenance.

3
Mario T. Lanza

Code lisible et maintenable: Code que, à première vue, un programmeur peut comprendre suffisamment pour pouvoir facilement:

  • le réutiliser via son interface, ou
  • le déboguer, ou
  • changer son comportement. (ajouter/supprimer une fonction), ou
  • l'optimiser
  • essaye-le

Cela se résume à la "clarté". C'est-à-dire combien de questions le programmeur doit-il poser à un segment de code particulier avant d'être sûr de `` comprendre ce qu'il fait assez bien '' pour accomplir la tâche en cours sans provoquer d'effets secondaires inattendus.

Le livre "Code Complete, de Steve McConnell" aborde ce sujet en détail.

Il passe par diverses métriques que vous pouvez utiliser pour déterminer si le code est de bonne qualité.

Voir un exemple ici: http://books.google.co.uk/books?id=3JfE7TGUwvgC&lpg=PT376&pg=PT389#v=onepage&q&f=false

3
JW01

minimiser les effets secondaires (idéalement n'en avoir aucun)

Une fonction qui provoque 3 changements d'états en dehors de sa propre portée est beaucoup plus difficile à raisonner et à maintenir qu'une fonction qui ne fait qu'entrer et sortir quelque chose d'autre. Vous ne pouvez pas simplement savoir ce que fait la fonction, vous devez vous rappeler ce qu'elle a fait et comment cela affecte toutes les autres fonctions pertinentes.

Pour OOP minimiser les effets secondaires signifie également des classes avec moins de membres, et surtout moins de membres qui peuvent modifier l'état de la classe, car les fonctions membres peuvent modifier des états au-delà des leurs et avoir des effets secondaires (elles peuvent manipuler le Cela signifie également des classes avec moins de membres de données propres afin qu'il y ait moins d'état pour ces méthodes à falsifier et moins d'effets secondaires qu'elles peuvent provoquer.

À titre d'exemple simple, imaginez essayer de concevoir une structure de données sophistiquée qui peut maintenir un état sorted qu'il utilise pour déterminer s'il faut effectuer des recherches binaires ou linéaires. Dans un tel cas, il pourrait être utile de séparer la conception en deux classes. L'appel de sorted sur la classe non triée peut alors renvoyer une structure de données d'une autre classe qui conserve toujours son contenu trié. Vous avez maintenant moins d'effets secondaires (donc moins de code sujet aux erreurs et plus faciles à comprendre) ainsi qu'un code plus largement applicable (l'ancienne conception serait inutile à la fois en termes de traitement et d'efficacité intellectuelle humaine pour les petits tableaux qui n'ont jamais besoin d'être triés).

Évitez les dépendances externes superflues

Vous pourriez être en mesure d'implémenter le code le plus laconique imaginable avec une réutilisation maximale du code en utilisant 13 bibliothèques différentes pour accomplir une tâche relativement simple. Cependant, cela transfère les frais généraux intellectuels à vos lecteurs en les obligeant ensuite à comprendre au moins des parties de 13 bibliothèques différentes. Cette complexité inhérente devrait être immédiatement appréciée par toute personne qui a essayé de construire et de comprendre une bibliothèque tierce qui nécessitait de tirer et de construire une douzaine d'autres bibliothèques pour fonctionner.

C'est probablement un point de vue très controversé, mais je préférerais une duplication de code modeste à l'extrême opposé à condition que le résultat final soit bien testé (rien de pire qu'un code défectueux non testé dupliqué plusieurs fois). Si le choix est entre 3 lignes de code dupliqué pour calculer un produit vectoriel croisé ou en tirant dans une bibliothèque mathématique épique juste pour raser 3 lignes de code, je suggérerais la première à moins que toute votre équipe ne soit à bord de cette bibliothèque mathématique , auquel cas vous pourriez toujours envisager d'écrire simplement 3 lignes de code au lieu de 1 si c'est assez trivial en échange des avantages du découplage.

La réutilisation du code est un acte d'équilibrage. Réutilisez trop et vous transférez la complexité intellectuelle d'une manière un à plusieurs, car dans ces 3 lignes de code simple que vous avez enregistrées ci-dessus, cela coûte aux lecteurs et aux mainteneurs de comprendre bien plus d'informations que 3 lignes de code . Cela rend également votre code moins stable, car si la bibliothèque mathématique change, votre code pourrait également changer. Réutilisez trop peu et vous multipliez également les frais généraux intellectuels et votre code cesse de bénéficier d'améliorations centrales, c'est donc un acte d'équilibrage, mais l'idée qu'il s'agit d'un acte d'équilibre mérite d'être mentionnée car essayer d'éliminer chaque petite forme de duplication modeste peut conduire à un résultat aussi difficile à maintenir, sinon plus, que l'extrême opposé.

Testez la merde hors de lui

C'est une donnée, mais si votre code ne gère pas tous les cas d'entrée et manque certains cas Edge, alors comment pouvez-vous vous attendre à ce que les autres maintiennent le code que vous avez écrit que vous n'avez même pas obtenu juste avant qu'il ne soit transféré dans leurs yeux et leurs mains? Il est déjà assez difficile d'apporter des modifications à du code qui fonctionne parfaitement et encore moins à un code qui n'a jamais été tout à fait correct au départ.

En plus de cela, le code qui passe des tests approfondis trouvera généralement moins de raisons de changer. Cela concerne la stabilité qui est encore plus un Saint Graal à atteindre que la maintenabilité, car un code stable qui n'a jamais besoin d'être modifié n'entraîne aucun coût de maintenance.

Documentation d'interface

Priorisez "ce que les choses font" sur "comment les choses les font" si vous ne pouvez pas consacrer autant de temps à documenter les deux. Une interface claire qui est évidente dans ses intentions sur ce qu'il fera (ou à tout le moins, ce qu'il est censé faire) dans tous les cas d'entrée possibles donnera une clarté de contexte à sa propre mise en œuvre qui guidera la compréhension non seulement de la façon dont d'utiliser le code, mais aussi comment il fonctionne.

Pendant ce temps, le code qui manque de ces qualités où les gens ne savent même pas ce qu'il est censé faire est SOL peu importe la qualité de ses détails d'implémentation. Un manuel de 20 pages sur la façon dont le code source est mis en œuvre est sans valeur pour les personnes qui ne peuvent même pas comprendre exactement comment il est censé être utilisé en premier lieu et ce qu'il est même censé faire dans tous les scénarios possibles.

Pour l'implémentation, donnez la priorité à la documentation de ce que vous faites différemment des autres. Par exemple, Intel a une hiérarchie de volume englobante pour leurs noyaux de raytracing. Puisque je travaille dans ce domaine, je peux reconnaître l'essentiel de ce que fait leur code en un coup d'œil sans passer au crible la documentation. Cependant, ils font quelque chose d'unique qui est l'idée de traverser le BVH et d'effectuer des intersections en parallèle en utilisant des paquets de rayons . C'est là que je veux qu'ils priorisent leur documentation parce que ces parties du code sont exotiques et inhabituelles de la plupart des implémentations BVH historiques.

lisibilité

Cette partie est très subjective. Je ne me soucie pas vraiment de la lisibilité d'un type proche des processus de pensée humaine. Le code le plus bien documenté décrivant les choses au plus haut niveau est toujours difficile à suivre si l'auteur utilise des processus de pensée bizarres et compliqués pour résoudre un problème. Pendant ce temps, le code laconique utilisant 2 ou 3 noms de caractères peut souvent être plus facile pour moi de comprendre si la logique est très simple. Je suppose que vous pourriez passer en revue les pairs et voir ce que les autres préfèrent.

Je m'intéresse principalement à la maintenabilité et, plus important encore, à la stabilité. Le code qui ne trouve aucune raison de changer est celui qui n'a aucun coût de maintenance.

2
user204677

Voici une technique que j'aime utiliser:

Montrez le code à l'un de vos pairs programmeurs et demandez-leur de vous expliquer ce qu'il fait. Surveillez ces choses.

1) S'ils ne peuvent pas facilement expliquer l'objectif d'un bloc de code, refactorisez-le.
2) S'ils doivent passer à une autre section de code pour comprendre la section actuelle, refactorisez-la.
4) Chaque fois que vous ressentez le besoin de parler pendant le processus, cette section de code doit être refactorisée. (Le code ne parle pas de lui-même).

1
JohnFx

Je dirais qu'une façon de savoir serait que les nouveaux membres de l'équipe puissent récupérer le code, le comprendre et le modifier pour corriger les défauts/répondre aux nouvelles exigences avec une relative facilité.

Le code le plus facile à maintenir est le code qui n'est pas là. Ainsi, au lieu d'ajouter au nombre de LOC, un nouveau code qui `` réduit '' le nombre de LOC (même s'il est légèrement moins maintenable lorsqu'il est vu isolément) pourrait rendre la base de code totale plus maintenable simplement en réduisant sa taille. Ainsi, la règle principale pour le code maintenable:

  • maximiser SEC.

Deuxièmement, il n'y a rien de pire pour la maintenabilité que les dépendances cachées. Donc, pour la règle numéro 2:

  • Rendez toutes vos dépendances explicites.

Troisièmement, tous les programmeurs ne sont pas également qualifiés pour maintenir ou écrire en utilisant des fonctionnalités ou des idiomes de langage de techniques plus avancées spécifiques. Réduire toute la base de code vous donnera une grande base de code qui, en raison de sa taille, est difficile à maintenir. Permettre des fonctionnalités et des idiomes de techniques avancées dans tout le code rendra tout le code maintenable uniquement par les développeurs seniors, ce qui est également mauvais. La clé de la maintenabilité est la superposition basée sur le niveau de compétence. Par exemple:

Bibliothèques multi-projets: développeurs seniors, plein dos de trucs code/idiome/techniques Bibliothèques spécifiques au projet et backend système: développeurs intermédiaires, évitez les choses les plus avancées et difficiles à expliquer. Les seniors vont parcourir ce code à la recherche de DRY opportunités d'amélioration.

Front-end: développeurs juniors, utilisez un guide de style strict et un ensemble de techniques de langage et de langage à éviter. Les développeurs Medior vont parcourir ce code à la recherche de DRY opportunités et logique métier cachée.

Donc, pour la règle numéro 3:

  • Couchez votre code par niveau de compétence développeur et écrivez le code maintenable en conséquence.

Je

0
user1703394