Comment éviter de programmer de mauvaises habitudes, en particulier le copier-coller?

Les gens pensent que copier / coller est une mauvaise habitude. Ce n’est pas; il est tout simplement mal pris en charge dans les environnements de développement actuels.

La programmation Copier / Coller (j’appelle cela “Clonage”) est un moyen de rendre les programmeurs productifs : ils peuvent trouver quelque chose de similaire à ce qu’ils doivent faire, le copier et commencer à le changer. Mais, souvent, ils ne savent pas vraiment ce qu’ils veulent faire tant qu’ils n’ont pas terminé les modifications. Ils ne peuvent donc pas facilement éliminer les clones pendant leur fonctionnement; ils ne savent pas comment extraire les points communs jusqu’à ce que tous les changements / débogage soient terminés. Ainsi, ils clonent, corrigent et fournissent des résultats. Jusqu’ici tout va bien.

Ce qui est inefficace dans le clonage, c’est le coût induit sur la maintenance logicielle en aval.

Il s’avère que pratiquement chaque logiciel (d’au moins 100K SLOC), peu importe qui le code ou dans quelle langue il est codé, a au moins 10% de code cloné ; souvent, beaucoup plus. (C’est un sale secret que tout le monde connaît, bien qu’ils ne connaissent peut-être pas le pourcentage réel).

Cela signifie que si Joe modifie * une * ligne de la base de code, il y a 10% de chances qu’une ligne clonée équivalente existe ailleurs dans le logiciel. Si Joe n’inspecte pas au moins cette ligne, il peut ne pas propager correctement le correctif. Le coût de la correction d’un bug découvert dans la boutique représente environ 1% du coût de la correction d’un bug découvert sur le terrain. Donc, si Joe ne fait pas attention aux clones (combien de Joes existe-t-il?), Il augmente le coût moyen d’une correction de code par lot.

C’est la raison pour laquelle les gens souhaitent que les clones ne soient pas fabriqués en premier lieu.

Il y a un compromis heureux.

Laissez Joe cloner pendant qu’il code et corrige les choses. Cela le rend efficace à court terme. Ensuite, donnez à Joe un outil qui lui permet de voir où se trouvent les clones, afin qu’il corrige toutes les instances (peut-être en répétant un correctif, peut-être en faisant abstraction des clones et en corrigeant l’abstraction) à la fois. Cela rend Joe efficace dans
le long terme.

Pour ce faire, vous avez besoin d’un outil de détection de clone . Cela ne devrait pas surprendre les gens qui lisent ma biographie, de savoir qu’en tant que constructeur d’outils, j’en ai construit un.
CloneDR trouve des clones en comparant des structures de code (arbres de syntaxe abstraite) plutôt que du texte, en recherchant des quasi-accidents (clones paramétrés) plutôt que des clones exacts. (Le site contient des exemples de rapports de clonage). Cela signifie qu’il n’est pas dupe d’un code reformaté ou contient des correctifs internes; remarquablement CloneDR trouve des abstractions parce que c’est ce que les gens clonent! CloneDR est implémenté en utilisant les idées d’un article technique que j’ai écrit, qui est l’un des articles les plus référencés dans la littérature de recherche sur la détection des clones (oui, il y a une communauté de recherche intéressée par cela).

Donc: le clonage n’est pas mauvais . Ne pas suivre et gérer les clones: c’est mauvais.

Je trouve que le copier-coller n’est pas différent de la génération d’échafaudages. Vous supposez inconsciemment que le code qui est déjà généré pour vous fera le travail, et il y a de nombreux cas où vous ne vous trompez pas, même si la sagesse générale selon laquelle le copier-coller peut être mauvais est très vraie.

Dans toute entreprise, pensez aux conséquences potentielles avant d’ agir. Non seulement vous éviterez certains résultats négatifs, mais vous serez préparé à ceux qui ne peuvent être évités. Au fil du temps, les «mauvaises habitudes» remonteront à la surface et vous pourrez les éliminer. Peut-être que copier / coller sera l’un de ceux pour vous, mais peut-être pas pour les autres.

Concentrez-vous sur la vitesse et la qualité et ignorez les conseils désinvoltes des gars qui empilent les investissements en utilisant les diplômes que leurs parents les ont achetés. Vous êtes le maître de votre propre productivité.

La phrase est «Copier et modifier» et vous avez raison, c’est une mauvaise habitude. Si vous acceptez le principe Don’t Repeat Yourself (DRY), copier-modifier est par définition une violation des bonnes pratiques. Fondamentalement, si vous avez deux variantes sur un morceau de code donné, vous devriez avoir créé une abstraction partagée pour capturer la similitude.

Cela dit, il y a beaucoup d’utilisation de langages qui limitent la mesure dans laquelle on peut créer de telles abstractions communes. Fondamentalement, les types de polymorphisme disponibles dans les langues populaires sont limités et les gens sont plus ou moins obligés d’utiliser la copie et la modification.

Dois-je copier-coller-modifier un bloc de code, je laisserais un ” mot de suivi unique ” (Edit: astuce chapeau à Chris Messina, inventeur du hashtag, c’est ce que c’est) quelque part dans / tous / fichiers source, email lignes d’objet et corps, feuille de calcul / noms de fichiers /, fichier / noms de test /, validation des commentaires, fusion des commentaires, commentaires de publication, etc.

Par exemple, “TK-87734”.

Un système de suivi des bogues ou du travail peut fournir un numéro d’identification unique (“87734” ci-dessus); on peut préfixer ce numéro avec quelques lettres nommant le système de suivi des bogues ou du travail lui-même (“TK-” ci-dessus).

Ainsi, on obtient un ” mot de suivi unique ” à mettre dans les commentaires, les noms de fichiers, partout pertinents.

Deux ans plus tard:

  • Uh-oh, le code de John ne fonctionne pas. Oh, il y a un commentaire ‘// AVERTISSEMENT: utilisé ailleurs, voir
  • Ouvrez cet ancien système de suivi des bogues TK, recherchez-le “TK-87734”. Uh-oh, ça empire. De combien?
  • grep -r ‘TK-87734’ source-file-root # OK, maintenant je sais combien.
  • Oh, j’ai un e-mail avec “(TK-87734)” dans la ligne Objet. Recherchez mon e-mail pour cela. Ah, c’est pourquoi il a fait ça.
  • OK, nous devrions peut-être refactoriser cela.

J’utilise souvent le copier-coller pour gagner du temps, mais j’essaie de le faire de manière intelligente / robuste.

Par exemple, j’ajoute des espaces pour aligner les choses afin que la chose qui est censée changer soit dans la même colonne. Cela permet de repérer plus facilement une erreur.

object4.width = blah.x;
object4.height = tout.y;
item1.width = thingy.x;
item1.height = quelque chose.y;

c’est mieux que ça:

object4.width = blah.x;
object4.height = tout.y;
item1.width = thingy.x;
item1.height = quelque chose.y;

De plus, j’écrirai une ligne sans la chose à changer, je la copierai autant de fois que nécessaire, puis je remplirai manuellement le reste.

Par exemple, si vous déroulez une boucle, copiez ceci:

my_array[]. = my_vector[].

pour faire ceci:

my_array [0] .x = my_vector [0] .x
my_array [0] .y = my_vector [0] .y
my_array [1] .x = my_vector [1] .x
my_array [1] .y = my_vector [1] .y

my_array [63] .x = my_vector [63] .x
my_array [63] .y = my_vector [63] .y

Faites-en une fonction ou un composant réutilisable.

Si vous ne pouvez pas, ne vous appelez pas programmeur. Si vous pouvez mais pensez que ce n’est pas bon pour ce cas particulier, alors ne l’appelez pas une mauvaise habitude et allez prendre une autre pinte de bière.