Dénomination: faut-il sacrifier la brièveté pour plus de clarté?

11

Par exemple, la fonction suivante parcourt un tableau qui contient le nom et les erreurs d'un champ de saisie. Pour ce faire, il vérifie le nom du champ de validation, puis envoie les informations d'erreur au tableau des champs non valides.

Est-il préférable d'être bref et d'écrire ceci:

addInvalidField (field, message) {
  const foundField = this.invalidFields.find(value => {
    return value.name === field.name
  })
  const errors = foundField.errors
  if (!errors.some(error => error.name === message)) {
    errors.push({ name: message, message })
  }
},

Ou être plus précis comme ça?

addInvalidField (validatingField, message) {
  const foundField = this.invalidFields.find(invalidField => {
    return validatingField.name === invalidField.name
  })
  if (!foundField.errors.some(foundFieldError => foundFieldError.name === message)) {
    fouldField.errors.push({ name: message, message })
  }
},
alex
la source
1
liés (éventuellement un doublon): Existe
moucher
N'ayez pas envie d'écrire une réponse, mais nous essayons toujours de trouver un bon compromis entre la longueur du nom et la clarté. Les noms courts peuvent être évidents pour le programmeur d'origine mais pas pour tout le monde. Les noms longs peuvent rendre le code difficile à lire. Il y a un compromis entre les deux.
MetalMikester
1
a besoin de plus de commentaires
Ewan
Remarque, et je ne sais pas si c'est possible dans votre code, mais si invalidFields etc. étaient stockés dans une carte , pas un tableau , ce code deviendrait beaucoup plus simple.
user949300
1
@alex En réponse à votre commentaire, si vous pouvez obtenir ou emprunter une copie de Eloquent JavaScript par Marijn Haverbeke, (version 2014), allez aux pages 73-75 pour voir un excellent exemple d'utilisation d'une carte au lieu d'un tableau. J'espère que ça t'as aidé.
user949300

Réponses:

23

Si la brièveté peut être sacrifiée pour plus de clarté, elle le devrait. Mais si la verbosité peut être sacrifiée pour plus de clarté, c'est encore mieux.

addInvalidField (field, message) {
  const foundInvalidField = this.invalidFields.find(x => x.name === field.name)
  if (!foundInvalidField.errors.some(x => x.name === message)) {
    foundInvalidField.errors.push({ name: message, message })
  }
},

Lorsqu'une variable ne vit que le temps d'une ligne, elle peut en effet être très courte. FoundInvalidFieldest utilisé en trois lignes et est au centre de ce travail. Il mérite un nom explicatif.

Comme toujours, le contexte est roi.

candied_orange
la source
2
+1 pour "Si la brièveté peut être sacrifiée pour la clarté, elle le devrait. Mais si la verbosité peut être sacrifiée pour la clarté, c'est encore mieux." Même lorsque je m'efforce de clarté presque en toutes circonstances. Mais c'est définitivement une citation citable.
Tulains Córdova
12

Je préfère en fait votre premier exemple de code.

On voit clairement ce que fait le code rien qu'en le lisant. En gardant les noms de variables aussi petits que possible, vous rendez le code encore plus facile à lire. Des noms de variables plus descriptifs ne seraient nécessaires que si vos fonctions étaient plus longues, vos variables étaient plus nombreuses et / ou les variables étaient utilisées sur une plus grande portée de code.

C'est parce que vous avez gardé vos fonctions brèves que vous pouvez également garder vos noms de variables brèves. Toutes choses étant égales par ailleurs, moins de code est toujours meilleur.

Robert Harvey
la source
2
Pour me baser sur cela, en règle générale, je préfère des noms de variable plus petits pour mes méthodes / fonctions. La seule fois où j'utiliserais un nom plus verbeux, c'est s'il y a un conflit d'espace de noms. Si la taille de votre fonction est petite, cela est également plus facile à réaliser.
unflores
4
J'ai travaillé avec quelqu'un qui était vraiment gros dans les noms verbeux. les variables et les noms de méthodes étaient essentiellement des phrases anglaises complètes, par exemple theResultOfMethodDoFooWithBar. L'idée était que cela était censé clarifier les choses, mais cela m'a donné mal à la tête en essayant d'analyser (mentalement) tout ce fluff. Pour cet exemple, nous savons déjà que la méthode concerne les validations de champs. Il n'y a pas d'autres paramètres de «champ». L'utilisation d'un nom tel que «validatingField» n'ajoute aucune clarté et masque les informations importantes lors du survol.
JimmyJames
@unflores J'essaie aussi de faire ça. validatingFieldssont des champs de formulaire avec validation. Le nom d'origine était fieldWithValidation. Il est vraiment difficile de trouver un nom court pour celui-ci. Je pourrais l'appeler simplement, fieldmais alors il y aura un conflit avec un autre fieldà l'intérieur de la méthode.
alex
4

Je pense que je suis d'accord avec l'oncle Bob sur la préférence pour la clarté sans encourir une verbosité excessive . Dans les exemples que vous montrez, je dirais que l'intention du second est plus claire sans encourir une verbosité excessive . Il serait également plus facile de trouver cet extrait particulier lors de la recherche dans la base de code de invalidFieldque pour value.


Eh bien, je cite Clean Code ici (sautez-le si vous en avez marre de la prédication de l'oncle Bob (ce que je ne suis pas):

Utiliser des noms révélateurs d'intentions

Il est facile de dire que les noms doivent révéler l'intention. Ce que nous voulons vous faire comprendre, c'est que nous sommes sérieux à ce sujet. Choisir de bons noms prend du temps mais économise plus qu'il n'en faut. Faites donc attention à vos noms et changez-les lorsque vous en trouverez de meilleurs. Quiconque lit votre code (y compris vous) sera plus heureux si vous le faites.


Évitez la désinformation

Les programmeurs doivent éviter de laisser de faux indices qui obscurcissent la signification du code. Nous devons éviter les mots dont la signification enracinée diffère de notre


Faites des distinctions significatives

Les programmeurs se créent des problèmes lorsqu'ils écrivent du code uniquement pour satisfaire un compilateur ou un interprète.


Utiliser des noms consultables

Utilisez des noms qui vous aideraient à faire un grep -iIR whateveryouaresearching . (pas un code propre, ici CC ne parlait que de variables à lettre unique).


Évitez la cartographie mentale

Les lecteurs ne devraient pas avoir à traduire mentalement vos noms en d'autres noms qu'ils connaissent déjà. Ce problème découle généralement du choix de n'utiliser ni termes de domaine à problème ni termes de domaine de solution.


Utiliser des noms de domaine problématiques

Lorsqu'il n'y a pas de «programmeur-eese» pour ce que vous faites, utilisez le nom du domaine problématique. Au moins, le programmeur qui gère votre code peut demander à un expert en domaine ce que cela signifie.


Tulains Córdova
la source
1

Je choisirais toujours d'être plus descriptif ces jours-ci - l'achèvement du code IDE signifie que vous n'aurez pas à écrire des noms de variables descriptives, donc je ne vois pas d'inconvénient.

Dans la préhistoire, vous aviez des restrictions de nom de variable et l'utilisation de noms de variable significatifs pouvait en fait engendrer un coût mesurable (par exemple dans BBC BASIC en utilisant les variables statiques entières A% etc. était beaucoup moins cher que d'utiliser un entier significatif - et dans un système avec 1 MHz processeur, économiser quelques cycles d'horloge dans une boucle importait vraiment)

mcottle
la source
6
L'inconvénient n'est pas que vous devez taper beaucoup. La frappe ne se produit qu'une seule fois. L'inconvénient des noms trop longs est que la lecture devient plus difficile. Et c'est insidieux parce que la lecture se produit plusieurs fois pendant la durée de vie de la base de code, et parce que les gens ne remarquent pas consciemment la source du problème parce que la lecture est tellement enracinée.
Kilian Foth
Et si vous devez passer du temps et des changements de contexte à essayer de vous souvenir de quelque chose à propos d'une variable parce qu'elle n'était pas suffisamment descriptive, cela vous coûtera plus de temps :).
mcottle
1

La seconde variante me rend perplexe. Quand je regarde seulement la signature, je me demande si le champ est déjà connu comme étant invalide? Ou sera-t-il validé en premier (comme on l'appelle validatingField), pour savoir s'il est vraiment invalide? Il ne s'agit donc pas seulement d'informations redondantes, mais les informations supplémentaires semblent quelque peu trompeuses. Ce genre de "clarté" n'est pas plus clair, c'est le contraire.

En fait, quand j'ai vu votre première fonction, cela m'a aussi rendu perplexe. Je me suis demandé pourquoi diable votre fonction prend-elle simplement un champ, mais ne l'utilise pas et en recherche un autre dans invalidFields? La recherche d'un champ semble beaucoup plus logique quand il n'y a qu'un nom de champ, comme ceci:

addInvalidField (fieldname, message) {
  const foundField = this.invalidFields.find(value => {
    return value.name === fieldname
  })
  const errors = foundField.errors
  if (!errors.some(error => error.name === message)) {
    errors.push({ name: message, message })
  }
}

Cependant, je suppose que Bob Martin irait probablement plus loin et rendrait le code plus verbeux - pour plus de clarté - dans une direction différente. Un refactoring typique dans le sens du livre "Clean Code" ressemblerait probablement à ceci:

addInvalidField (fieldname, message) {
  const foundField = findInvalidField(fieldName)
  addMessageForInvalidField(foundField,message)
}

avec trois fonctions supplémentaires

  findInvalidField(fieldname){
    return this.invalidFields.find(value => { return value.name === fieldname })
  }

  addMessageForInvalidField(field,message){
    const errors = field.errors
    if (!doesErrorsContain(message)) {
      errors.push({ name: message, message })
    }
  }

  doesErrorsContain(message){
     return errors.some(error => error.name === message)
  }

Il est discutable s'il est avantageux d'aller aussi loin avec le principe de la responsabilité unique. Il a en fait des avantages et des inconvénients. Mon point de vue personnel est que le code d'origine est "assez propre" pour la plupart des codes de production, mais le refactorisé est meilleur.

Quand je savais que je devais ajouter quelque chose à la première variante pour qu'elle grandisse de plus en plus, je le divisais à l'avance en ces petites fonctions, afin que le code ne commence même pas à devenir un gâchis.

Doc Brown
la source
validatingFieldssont des champs d'un formulaire qui ont une validation. Au départ, je les ai nommés fieldsWithValidationmais c'était un peu long.
alex
0

Il n'y a pas de bonne réponse en général dans la dénomination. Beaucoup de gens, lorsqu'ils reçoivent exactement le même ensemble de tâches, nommeront les fonctions et les variables résultantes de manière très différente. Bien sûr, vous voulez que les autres qui lisent votre code comprennent, mais plus ne signifie pas toujours que quelque chose est plus clair. Si votre code est plus dense, il doit l'être, alors il faudra plus de temps pour comprendre que même chaque ligne de vos fonctions est aussi claire et descriptive que possible.

Personnellement, j'aime davantage le premier exemple. C'est simple et au point même avec les variables n'ayant pas de noms descriptifs comme dans le deuxième exemple. Honnêtement, les noms de variables dans le deuxième exemple ne sont pas beaucoup plus clairs que le premier à mon avis et garder la fonction brève facilite la compréhension de la fonction elle-même.

À la fin de la journée, le mieux dépendra de vous et de la personne avec qui vous travaillez. Après tout, c'est qui le lira et le maintiendra.

Dom
la source