web-dev-qa-db-fra.com

Code propre: noms longs au lieu de commentaires

N'ayez pas peur de faire un nom longtemps. Un nom descriptif long est meilleur qu'un bref nom énigmatique. Un long nom descriptif est meilleur qu'un long commentaire descriptif.

Robert C. Martin

Ai-je compris Clean Code Droite? Vous mettez toutes les informations que vous mettriez dans un commentaire dans la classe/la méthode/... Nom. Cela ne conduirait-il pas à de longs noms comme:

PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments
PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions
41
TomatenSalat

Oui, vous comprenez code propre droite, mais vos exemples sont tout à fait un peu plus haut.

Voici ce que vous commencez avec:

PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments 
PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

Une " page Reloader " vraisemblablement pages recharge, de sorte que la partie " Pages " est redondante. Cela vous laisse avec:

PageReloaderForDisplayingVectorGraphicsThatAreUsedInTheEditorComments 
PageReloaderForDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

Les pages sont toujours des choses affichaient, de sorte que le Displaying partie est trop redondante,. Cela vous laisse avec:

PageReloaderForVectorGraphicsThatAreUsedInTheEditorComments 
PageReloaderForVectorGraphicsThatAreUsedInTheEditorDescriptions

En anglais, les constructions de ce genre qui est-utilisés en qui peut être reformulé comme ce-ce. Par exemple, la coloration qui-est-utilisé-nourriture est-colorant alimentaire. En appliquant cette règle, vous laisse avec:

PageReloaderForEditorCommentsVectorGraphics 
PageReloaderForEditorDescriptionsVectorGraphics

Aussi en anglais, des constructions de ce genre-pour-qui peut être reformulé comme ce-ce. Par exemple, bouteille pour l'eau peut être reformulée comme bouteille d'eau. En appliquant cette règle, vous laisse avec:

EditorCommentsVectorGraphicsPageReloader
EditorDescriptionsVectorGraphicsPageReloader

Et puis bien sûr il peut y avoir d'autres raccourcis que vous pouvez appliquer.

Par exemple, dans votre système, vous n'avez probablement pas beaucoup de types de transbordeurs. Vous probablement avez transbordeurs page, donc cela vous laisse avec:

EditorCommentsVectorGraphicsReloader
EditorDescriptionsVectorGraphicsReloader

De plus, quand vous parlez de " vecteur " dans votre système, il peut être assez clair que vous parlez des " graphiques vectoriels ", donc cela vous laisse avec:

EditorCommentsVectorReloader
EditorDescriptionsVectorReloader

... et je pense que ce sont une très bonne façon réaliste des noms longs.

150
Mike Nakis

Non, oncle Bob ne dit pas ça.

Son livre n'a aucun rôle indiquant que vous devez mettre tous les commentaires dans le nom de la classe, "Toute l'information" que vous avez mentionnée.

Vous n'avez probablement pas besoin de "Pagereloader pour les pages spécifiques affichant des graphiques vectoriels, etc." et doit utiliser le même Pagereloader pour toutes sortes de pages.

Dans son livre, il y a beaucoup d'exemples de ce qu'il signifie exactement avec "remplacer de courts noms énigmatiques par des descriptifs significatifs" descriptifs ".

26
RubioRic

Il y a toujours un équilibre à frapper. Habituellement, lorsque des experts logiciels parlent, ils traitent d'un problème couramment compris de leur temps et de leur place.

Si les noms sont si non-descriptifs et énigmatiques qu'ils nécessitent des explications - comme à l'aide de F, g et h, comme les paramètres d'une méthode - alors dans la première place, ils doivent être allongés et rendu plus descriptifs.

Il y avait une période lorsqu'il était considéré comme un problème important pour que les programmeurs soient habituellement en utilisant des noms trop courts (souvent une lettre aléatoire), et les choses seraient radicalement améliorées simplement en utilisant un mot descriptif ou deux.

De nos jours, le problème opposé est souvent observé. Les programmeurs utilisant des noms de verbose inutilement, souvent une culture d'une terminologie hautement générale qui n'est pas particulièrement descriptive de rien.

Un exemple de ce dernier qui a récemment attrapé mon œil était des "applications" - je ne pouvais pas voir immédiatement comment cela était plus descriptif que "des programmes", "codestuff" ou même "Appsvcs".

"Vectorgraphics" pourrait sans doute être réduite à "lineart" sans perte de sens, mais même l'abréviation "vectgfx" serait probablement assez assez.

Donc, le principe de la création de noms descriptifs ne doit pas être lu comme une signification faire des noms aussi longtemps que possible. Il s'agit d'utiliser des noms contenant une densité d'informations élevée.

Un élément qui consiste toujours à être économique avec des syllabes et des personnages et de s'appuyer sur des connaissances implicites, telles qu'une bonne maîtrise de la langue anglaise et la familiarité avec des concepts informatiques généraux.

15
Steve

Je suis d'accord avec cette réponse https://softwareengineering.stackexchange.com/a/409460/262662 par Mike Nakis, mais il y a plus.

De plus, vous pouvez blâmer et grouper une partie de cela. tel que

PageReloaders.EditorCommentsVector
PageReloaders.EditorDescriptionsVector

Ensuite, si vous aviez plus de variables avec des noms tout aussi longs, vous pouvez (seulement dans des fonctions courtes/blocs) ...

Reloaders = Utilities.Reloaders.PageReloaders;
Reloaders.EdtiorCommentsVector.doSomething(); // small scope only.
// equivalent to...
Utilities.Reloaders.PageReloaders.EdtiorCommentsVector.doSomething();

// And with prettier, so long as the segments are within about 40 characters, it doesn't matter.  As it will look like this:
ReallyLongPath
  .filledWithLongStrings
  .JustToGetTo
  .Utilities
  .Reloaders
  .PageReloaders
  .EditorCommentsVector
  .doSomething();

Mise à jour

Si je devais réellement venir avec mes propres noms, basé sur l'original, au lieu de la réponse de Naki, j'utiliserais ce qui suit.

PageReloaders.VectorGraphicsPages.EditorComments
PageReloaders.VectorGraphicsPages.EditorDescriptions

Ou peut-être

PageReloaders.EditorComments.WithVectorGraphics
PageReloaders.EditorDescriptions.WithVectorGraphics

Mais honnêtement, cela dépend de la quantité de choses que vous avez continue. Si vous avez vraiment besoin d'un téléchargement différent pour Editordscriptions, ou un autre pagereloader pour les pages vecteurGraphics vs normales? pages vs pages en clair, alors tu dois faire ce que tu dois faire. Si vous n'avez pas beaucoup de choses, comme si une page peut ou non avoir des graphiques vectoriels, allez simplement avec PageReloaders.EditorComments. N'ayez pas peur de changer vos noms de variables comme un projet grandit. Et n'utilisez pas de choses comme pgrldr.VGraph.EtrCmnt Pour essayer d'obtenir des noms de variables plus courts. Juste ne le fais pas. L'objectif est de réduire la quantité de contrainte cérébrale sur les futurs développeurs (y compris vous-même) lorsque vous essayez de déterminer ce que vous avez fait la première fois.

Mise à jour finale

Je crois que Robert C. Martin faisait réellement référence à ce qui suit:

<!-- We actually had this in our codebase -->
<button class="btn-submit pers pers_cp"></btnbutton

<!-- What it meant, using the Clean Code standards -->
<button class="btn-submit btn-personnel_module btn-copy_action"></button> 

Ce bouton a été copié/collé sur tous les modules et aux actions qui n'étaient pas copie. Lors de l'écriture de CSS, les gens ne savaient pas ce que les classes signifiaient, alors ils ont utilisé ces classes pour dimensionnement, au lieu de couleurs seulement. C'était l'enfer de le déterrer.

Cela s'applique également à des boucles. Qu'est-ce qui est mieux...? (encore une fois, effectivement tiré de notre codebase)

for (let k=0; k < vehsAr.length; k++) {
  let vehs = vehsAr[k];
}
/*---- OR -----*/
for (let vehicleIndex=0; vehicleIndex < vehiclesArray.length; vehicleIndex++) {
  let vehicle = vehiclesArray[vehicleIndex];
}

Avec la boucle for(i), si j'ai décidé de changer le niveau de nidification, je finirais de réutiliser i puis de devoir tout déplacer tout à l'intérieur de k. Si je suis plutôt utilisé des variables descriptives, il y a moins de travail à faire. Un petit effort va de loin.

for (let r = 0; r < width; r++) {
  for (let c = 0; c < height; c++) {
    grid[r][c].doSomething();
    // I see immediately that rows is the first layer, and columns is the second layer.
    // "row" and "column" is better than "r" and "c", but "r" and "c" still go a long ways.
    invertedGrid[c][r].doSomething(); // If it goes in natural English reading order, I only have to check in one spot that r and c are backwards.
  }
}
// Invert the nesting order
for (let c = 0; c < height; c++) {
  for (let r = 0; r < width; r++) {
    grid[r][c].doSomething();
    invertedGrid[c][r].doSomething();
    // Notice how the inner formulas don't change?
    // If I used 'i' and 'k', convention is that 'i' is top layer, then 'j', then 'k', then 'l' which looks like '1'.  It get messy.
    // If I swapped height/width while using 'i' and 'k', I'd have to put in much more brain power to make sure height matched with the right letter and that letter matched with the right spot.

  }
}

mise à jour en utilisant i _ j _ et k in for Loops est parfaitement acceptable et est le plus courant façon d'écrire une boucle. Mais la norme de code de nettoyage, basée sur ce que je l'ai lu, n'aime pas cela. Du tout. Tout comme des virgules traînantes de 1,0 Prettier 1.0 et plus Polyttier 2.0 aime les virgules traînant. C'est une norme. Cela a une raison derrière elle. Ce n'est pas le seul moyen. Mais en utilisant des noms variables plus longs et plus descriptifs, la directive relative aux normes étant examinée ici.

10
RoboticRenaissance

Ce que je sortirais de ceci est quand vous avez des articles comme:

PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorComments
PageReloaderForPagesDisplayingVectorGraphicsThatAreUsedInTheEditorDescriptions

ensuite, ce que vous manquez de contexte, que vous avez trop d'articles de niveau supérieur qui méritent d'être regroupés de manière logique et que ce regroupement fournit un contexte. Bien que ce soit un exemple extrême, il pourrait peut-être être refacturé comme suit:

Comments.Editor.Page.Reloader
Descriptions.Editor.Page.Reloader

(ou peut-être peut-être page.commation.editor.reloader, quoi que ce soit!) Où les informations sur la question de savoir si la page affiche des graphiques vectorielles ou non fait partie du type de la page, voire même le reloadeur.

Les noms de variables n'existent pas isolément, ils sont assis dans le contexte d'autres objets et ont des types, tous ces contribuent à la compréhension.

Si vous avez un nom qui devient trop longtemps, déterminez si la variable elle-même porte trop de fardeau.

6
johnnysaucepn

N'oubliez pas que la partie de l'auditoire de ce livre est des programmeurs plus âgés qui se coupent leurs dents sur de vieux compilateurs qui avaient des limites de longueur de nom très courtes. La première norme de langage C nécessitait uniquement les compilateurs nécessaires pour traiter les premiers six caractères d'identificateurs visibles externes comme significatifs (C89 SPEC Section 3.1.2 ). Les fonctions et types de la bibliothèque standard C ont des noms extrêmement terribles, parfois au point où ils peuvent confondre le peu familier.

J'ai toujours interprété le conseil de Martin comme plus une condamnation des vieilles habitudes qui traitent l'espace horizontal de l'écran comme une chose qui devrait être prise en compte. Les compilateurs modernes ne se soucient pas vraiment des longueurs de noms et des programmeurs (pour la plupart) ne rédougent pas de code sur une console limitée à 80 colonnes. Les avantages des noms clairement lisibles dépassent de loin les avantages que vous bénéficiez de noms courts (ou trop longs).

Par exemple, la bibliothèque standard C a une fonction appelée mbstowcs(). Pouvez-vous dire ce que cette fonction fait? Moi non plus. Martin dit que les noms compressés comme celui-ci ne tiennent pas beaucoup de valeur. Si la fonction a plutôt été nommée ConvertMultibyteStringToWchar(), vous pouvez probablement affiner le code qui l'utilise sans avoir à creuser par la documentation.

Ceci est certainement ​​Pas de remplacement des commentaires. Commentaires Enregistrer Toutes sortes d'informations supplémentaires, comme si l'appelant doit libérer la mémoire renvoyée par la fonction, quelles exceptions la fonction peut lancer, que la fonction est thread-coffre-fort, etc. Les commentaires enregistrent également des choses comme pourquoi La fonction est mise en œuvre de la manière dont elle est. Il s'agit de toutes les informations que vous ne pouvez pas raisonnablement tomber dans un nom, quel que soit le temps que vous le faites.

Je pense que le seul cas où les noms plus longs peuvent remplacer des commentaires est dans des cas comme celui-ci:

// tokenize a string
char *strtok(char *s1, const char *s2)
{
    ...
}

Mais si c'est ​​toutes les informations que vous documentez sur une fonction, les noms ne sont pas votre problème n ° 1.

3
bta

Le commentaire est intrinsèquement dangereux.

  • Utilisez-le avec parcimonie pour // fixmes

Pourquoi dangereux?

  • Le code vient et aller, mais les commentaires sont toujours laissés derrière.
  • Les gens craignent de supprimer des commentaires, car ils supposent que ce soit des informations vitales vraies.
  • Essayez de comprendre le code avec des informations essentielles vitales.

Je considère mauvais commentant, l'une des couches les plus profondes de la programmation de l'enfer.

Un nom de la fonction [par exemple] [par exemple] est toutefois moins susceptible de devenir inexact lorsque vous modifiez les choses en elle, et si ses fonctionnalités changent, vous êtes naturellement plus susceptible de changer le nom.

C'est une raison fondamentale mais importante pour laquelle un nom long est préférable sur des commentaires et pourquoi cela conduira à un code plus propre.

2
Akiva