Nombramiento: ¿Deberías sacrificar la brevedad por la claridad?

11

Por ejemplo, la siguiente función recorre una matriz que contiene el nombre y los errores de un campo de entrada. Para ello, verifica el nombre del campo de validación y luego envía la información de error a la matriz de campos no válidos.

¿Es mejor ser breve y escribir esto:

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 })
  }
},

¿O ser más específico como este?

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
fuente
1
relacionado (posiblemente un duplicado): ¿Hay una excusa para nombres cortos de variables?
mosquito
No tengo ganas de escribir una respuesta, pero siempre tratamos de encontrar un buen compromiso entre la longitud del nombre y la claridad. Los nombres cortos pueden ser obvios para el programador original, pero no para todos los demás. Los nombres largos pueden hacer que el código sea difícil de leer. Hay un compromiso en el medio.
MetalMikester
1
necesita más comentarios
Ewan
Nota al margen, y no estoy seguro de si es posible en su código, pero si los campos inválidos, etc., se almacenaron en un mapa , no en una matriz , este código sería mucho más simple.
usuario949300
1
@alex En respuesta a su comentario, si puede obtener o pedir prestada una copia de Eloquent JavaScript de Marijn Haverbeke, (versión 2014) vaya a las páginas 73-75 para ver un excelente ejemplo de uso de un mapa en lugar de una matriz. Espero que ayude.
user949300

Respuestas:

23

Si se puede sacrificar la brevedad por claridad, debería hacerlo. Pero si se puede sacrificar la verbosidad por claridad, aún mejor.

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 })
  }
},

Cuando una variable solo vive una línea, puede ser muy corta. FoundInvalidFieldse utiliza en tres líneas y es el foco de este trabajo. Se merece un nombre explicativo.

Como siempre, el contexto es el rey.

naranja confitada
fuente
2
+1 para "Si la brevedad se puede sacrificar por claridad, debería hacerlo. Pero si la verbosidad se puede sacrificar por claridad, aún mejor". Incluso cuando me esfuerzo por la claridad en casi todas las circunstancias. Pero eso es definitivamente una cita citable.
Tulains Córdova
12

De hecho, estoy a favor de tu primer ejemplo de código.

Es evidente lo que hace el código con solo leerlo. Al mantener los nombres de las variables lo más pequeños posible, hace que el código sea aún más fácil de leer. Los nombres de variables más descriptivos solo serían necesarios si sus funciones fueran más largas, sus variables fueran más numerosas y / o las variables se usaran en un alcance de código más grande.

Debido a que ha mantenido breves sus funciones, también puede mantener breves sus nombres de variables. En igualdad de condiciones, menos código siempre es mejor.

Robert Harvey
fuente
2
Para aprovechar esto, como regla general, prefiero nombres de variables más pequeños para mis métodos / funciones. La única vez que usaría un nombre más detallado es si hay un conflicto de espacio de nombres. Sin embargo, si el tamaño de su función es pequeño, esto también es más fácil de lograr.
Desplega el
44
Trabajé con alguien que era muy aficionado a los nombres detallados. Las variables y los nombres de los métodos eran básicamente oraciones completas en inglés, por ejemplo, theResultOfMethodDoFooWithBar. La idea era que se suponía que esto aclararía las cosas, pero me dio dolor de cabeza tratar de analizar (mentalmente) toda esa pelusa. Para este ejemplo, ya sabemos que el método se trata de validaciones de campo. No hay otros parámetros de 'campo'. El uso de un nombre como 'validatingField' no agrega claridad y oscurece la información importante al desnatar.
JimmyJames
@unflores también trato de hacer eso. validatingFieldsson campos de formulario con validación. El nombre original fieldWithValidation. Es realmente difícil encontrar un nombre corto para este. Podría llamarlo simplemente, fieldpero luego entrará en conflicto con otro fielddentro del método.
alex
4

Creo que estoy de acuerdo con el tío Bob en preferir la claridad sin incurrir en excesiva verbosidad . En los ejemplos que muestra, diría que la intención del segundo es más clara sin incurrir en excesiva verbosidad . También sería más fácil encontrar ese fragmento en particular al buscar a través de la base de código invalidFieldque por value.


Bueno, estoy citando Clean Code aquí (sáltelo si está harto de la predicación del tío Bob (que no estoy):

Utilice nombres reveladores de intenciones

Es fácil decir que los nombres deben revelar la intención. Lo que queremos impresionarle es que nos tomamos en serio esto. Elegir buenos nombres lleva tiempo, pero ahorra más de lo que lleva. Así que tenga cuidado con sus nombres y cámbielos cuando encuentre mejores. Todos los que lean su código (incluido usted) serán más felices si lo hace.


Evitar la desinformación

Los programadores deben evitar dejar pistas falsas que oscurecen el significado del código. Deberíamos evitar palabras cuyos significados arraigados difieran de nuestro


Hacer distinciones significativas

Los programadores se crean problemas cuando escriben código únicamente para satisfacer a un compilador o intérprete.


Usar nombres de búsqueda

Use nombres que lo ayudarían a hacer un grep -iIR whateveryouaresearching . (no un Código Limpio, aquí CC solo habló sobre variables de una sola letra).


Evitar mapeo mental

Los lectores no deberían tener que traducir mentalmente sus nombres a otros nombres que ya conocen. Este problema generalmente surge de la elección de no usar términos de dominio problemáticos ni términos de dominio de solución.


Usar nombres de dominio problemáticos

Cuando no hay "programador-eese" para lo que está haciendo, use el nombre del dominio del problema. Al menos el programador que mantiene su código puede preguntarle a un experto en el dominio qué significa.


Tulains Córdova
fuente
1

Siempre optaría por ser más descriptivo en estos días: la finalización del código IDE significa que no tendrá que escribir nombres de variables descriptivas para que no pueda ver un inconveniente.

En la prehistoria, tenía restricciones de nombres variables y el uso de nombres de variables significativos en realidad podía incurrir en un costo medible (por ejemplo, en BBC BASIC usar las variables estáticas enteras A%, etc. era mucho más barato que usar un entero significativo, y en un sistema con 1MHz procesador, ahorrando algunos ciclos de reloj en un bucle realmente importó)

mcottle
fuente
66
La desventaja no es que tienes que escribir mucho. Escribir solo ocurre una vez. La desventaja de los nombres que son demasiado largos es que la lectura se vuelve más difícil. Y eso es insidioso porque la lectura ocurre muchas veces a lo largo de la vida del código base, y porque la gente no se da cuenta de la fuente del problema porque la lectura está muy arraigada.
Kilian Foth
Y si tiene que pasar tiempo y cambios de contexto tratando de recordar algo sobre una variable porque no era lo suficientemente descriptiva, le costará más tiempo :).
mcottle
1

La segunda variante se ve me deja perplejo. Cuando solo miro la firma, me pregunto si el campo ya se conoce como no válido. ¿O se validará primero (como se le llama validatingField) para averiguar si realmente no es válido? Entonces, esto no es solo información redundante aquí, la información adicional parece ser algo engañosa. Este tipo de "claridad" no es más claro, es todo lo contrario.

En realidad, cuando vi tu primera función, también me dejó perplejo. Me pregunté por qué diablos su función solo toma un campo, pero luego no lo usa y busca otro invalidFields. Buscar un campo parece tener mucho más sentido cuando solo se da un nombre de campo, como este:

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 })
  }
}

Sin embargo, creo que Bob Martin probablemente iría un paso más allá y haría que el código sea más detallado, para mayor claridad, en una dirección diferente. Una refactorización típica en la línea del libro "Código limpio" probablemente se vería así:

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

con tres funciones adicionales

  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)
  }

Es discutible si vale la pena llegar tan lejos con el principio de responsabilidad única. En realidad tiene algunos pros y contras. Mi punto de vista personal es que el código original es "lo suficientemente limpio" para la mayoría del código de producción, pero el refactorizado es mejor.

Cuando supe que tenía que agregar algo a la primera variante para que creciera más y más, lo dividiría en estas funciones más pequeñas de antemano, para que el código ni siquiera comenzara a convertirse en un desastre.

Doc Brown
fuente
validatingFieldsson campos en un formulario que tienen validación. Inicialmente, los nombré fieldsWithValidationpero fue un poco largo.
alex
0

No hay una respuesta correcta en general al nombrar. Muchas personas cuando reciben exactamente el mismo conjunto de tareas nombrarán las funciones y variables resultantes de manera muy diferente. Por supuesto, quiere que otros que leen su código entiendan, pero más tiempo no siempre significa que algo está más claro. Si su código es más denso, entonces debe serlo, entonces llevará más tiempo comprender que incluso cada línea de sus funciones es tan clara y descriptiva como puede ser.

Personalmente, me gusta más el primer ejemplo. Es directo e ir al grano incluso con las variables que no tienen nombres tan descriptivos como en el segundo ejemplo. Honestamente, los nombres de las variables en el segundo ejemplo no son mucho más claros que el primero en mi opinión y mantener la función breve hace que sea más fácil entender la función en sí.

Al final del día, lo que sea mejor dependerá de usted y de quien sea que esté trabajando. Después de todo, es quien lo leerá y lo mantendrá.

Dom
fuente