Los nombres tienen poder
Phil Karlton enunció hace tiempo que uno de los dos grandes problemas de la programación es escoger nombres adecuados. Déjame echarte una mano con ello.
Desde hace un par de años, una de las cosas a las que más atención presto mientras programo es a la elección de nombres. Cada vez soy más consciente de que trabajar en equipo implica, entre otras muchas cosas, facilitar la vida al siguiente desarrollador que tenga que trabajar con mi código. Y eso pasa por encontrar nombres descriptivos para funciones, variables y el resto de elementos de la aplicación.
Existe un momento en la vida de cualquier programador en el que una idea crece dentro de él: “lo breve y comprimido es mucho mejor”. Es decir, que esto:
const finalValue = (cond1 && cond2) ? ( v > 0 ? 1 : 2) :
(c ? 3 : 4);
Es mucho mejor que esto:
let finalValue = null;
if (cond1 && cond2) {
if (v > 0) {
finalValue = 1;
} else {
finalValue = 2;
}
} else {
finalValue = c ? 3 : 4;
}
Por no hablar de nombres imposibles como:
const turic = 2;
Que son acrónimos de conceptos como “total of users registered in company”.
Salvo que nos cobren por línea o caracter escrito, creo que no hay motivos para cometer esta clase de atropellos. El siglo XXI llegó hace más de 20 años y con él una cosa tan maravillosa como es el autocompletado, que justo se inventó para ahorrarnos esas pulsaciones que tanta pereza nos dan.
Pasado un tiempo, habitualmente cuando nos cansamos de leer nuestros propios haikus, el péndulo interno se desplaza en la otra dirección, y comenzamos a emplear nombres larguíiiiiiiiisimos. ¡Como si esa fuera la solución!
Esto también representa un problema. Por ejemplo, un método con un nombre gigante provocará saltos de línea adicionales y evitará que de un vistazo podamos entender lo que hace. Lo mismo aplica para clases, variables o nombres de archivos.
🥷🏼 Para mí, un nombre tiene que ser todo lo largo que sea necesario pero no más. Tampoco menos.
Déjame darte algunos trucos que te ayuden a cumplir con la regla anterior.
Cómo escoger un buen nombre
Un nombre debe tener dos características:
Precisión: expresar lo que hace el elemento al que se lo hemos asignado.
Claridad: mostrar a lo que se refiere.
En el momento en que escojamos un nombre que cumpla estas dos cualidades, cualquier caracter adicional no aportará nada.
No añadas información extra
Por ejemplo, si estamos trabajando con un lenguaje tipado como TypeScript o las últimas versiones de PHP, la notación húngara es redundante:
function fn(nameString: string) {
El tipo de la variable es inherente a su propia declaración, por lo que no es necesario expresarlo también en su nombre. Aunque vayamos a trabajar con esa variable durante toda la función, no requerirá más de un scroll encontrar su tipo (si es que el editor no te lo proporciona ya al situar el cursor encima).
Psss. Entre tú y yo. Tus funciones no son de 500 líneas, ¿verdad? Ya hablaremos de eso en otra publicación.
Otro ejemplo sucede con las colecciones. Si queremos almacenar en una variable una lista de mascotas, es preferible usar el plural antes que recurrir a sufijos como List
o Collection
:
// 🥲
const petList = [];
// 😍
const pets = [];
Finalmente, si tu código está bien organizado tampoco es necesario provocar una sensación “eco” cuando escribimos métodos:
function orderUsers(users) {
// ..
}
// 🔈
orderUsers(users)
Aprovecha el contexto
El lenguaje tiene una característica muy poderosa (y de hecho, muy difícil de describir para una inteligencia artificial) que es el contexto. Esto es lo que permite este tipo de conversaciones:
¿Mañana llueve?
Sí.
¿Y pasado?
El significado de la segunda pregunta se infiere del contexto en el que tiene lugar la conversación.
En programación podemos aprovecharnos de él para escoger nombres que cumplan con nuestra promesa de claridad y precisión.
// 🥲
class Pet
{
function movePet() {
//
}
function feedPet() {
//
}
}
// 😍
class Pet
{
function move() {
//
}
function feed() {
//
}
}
Prescinde de palabras genéricas
Un truco que suele funcionar para saber si podemos eliminar una palabra del nombre que hemos asignado es tratar de borrarla mentalmente.
Por ejemplo, si nuestra variable se llama userInstance
, ¿qué sucede si nos cargamos ese sufijo tan rimbombante que es “Instance”? Nada, ¿verdad? Eso es porque no está aportando ningún tipo de significado más allá de que, cuando leamos el código en el futuro pensemos algo así como:
Uuuuuuh, una instancia!
data
, state
, amount
, value
, object
o entity
son ejemplos de este tipo de palabras que tan sólo aportan ruido a nuestro código. Pero valor, lo que se dice valor, muy poco.
Son identificadores, no libros
Al igual que debemos evitar el uso de abreviaturas ingeniosas a la hora de nombrar variables, tampoco es necesario escribir relatos cortos sobre lo que hace la variable.
Por ejemplo, partamos de una variable nombrada como commonProductsChoosenByUsersInCrossSelling .
Te prometo que he tenido que coger algo de aire para pronunciarla de carrerilla. Como idea inicial está bien, ya que no deja nada a la imaginación. La variable en cuestión representa los productos que los usuarios escogen durante el proceso de venta cruzada.
Pero no nos paremos ahí. Vamos a hacernos las siguientes preguntas:
¿Hay otra clase de participantes en nuestro sistema que puedan escoger productos? En caso negativo,
choosenByUsers
sobra completamente; no hay otro actor que pueda escoger productos en nuestra aplicación.¿Dónde se está usando esta variable? ¿Quizás en un componente llamado
CrossSelling
? En ese caso,InCrossSelling
no es necesario ya que el contexto donde se define la variable proporciona esa información.Y lo mismo sucede con el prefijo
common
. ¿Existe otra lista con productos no tan comunes?
Como ves, quizás no sea necesario un nombre tan largo. Entre cpcbuic
y commonProductsChoosenByUsersInCrossSelling
existe una amplia gama de nombres que harán nuestro código mucho más legible.
🏅 Recuerda la regla de oro. Un nombre tiene que ser todo lo largo que sea necesario pero no más. Tampoco menos.
Caso práctico
Como todo siempre se ve mejor con un ejemplo, partamos de la siguiente clase a la que aplicaremos un buen refactor en lo que a nombrado se refiere:
class LovelySephardDogClass {
public function moveLovelySephardDogThroughPoints(
array pointList
) { }
}
Como el argumento que recibe la función ya sabemos que es un array, podemos modificar su nombre a algo menos repetitivo:
class LovelyAndCuteDogClass {
public function moveLovelySephardDogThroughPoints(
array points
) { }
}
Lo mismo sucede con el sufijo “Class” que hemos añadido al nombre de nuestra clase. Ya sabemos que es una clase, ¿es necesario remarcarlo con 5 caracteres extra? No creo.
class LovelyAndCuteDog {
public function moveLovelySephardDogThroughPoints(
array points
) { }
}
Ahora toca hacernos la siguiente pregunta. ¿Existen en nuestra aplicación otro tipo de perros además de los “lovely and cute”? Si la respuesta es “no”, todos esos adjetivos que hemos añadido sobran:
class Dog {
public function moveDogThroughPoints(
array points
) { }
}
Por último, prestemos atención al método moveDogThroughPoints
. Puesto que se invocará sobre un objeto de la clase Dog
, no es necesario repetir el tipo de objeto que estamos moviendo. Recuerda: contexto, contexto, contexto:
class Dog {
public function moveThroughPoints(
array points
) { }
}
Y dado que el argumento que recibe el método moveThroughPoints
es una lista de puntos, creo que está claro que cuando invoquemos dog→move
, el objeto recorrerá la lista de puntos especificados. No es necesario hacer eco con “points”.
class Dog {
public function move(array points) { }
}
Ahora sí, podemos descansar tranquilos. 😌
Si estás pensando, "Gerardo, menudo ejemplo tan evidente me has puesto” te animo a que cojas una aplicación medio grande y le eches un vistazo. Quizás no encuentres una clase LovelyAndCuteDogClass
, pero me apuesto un café a que entre la maleza habrá nombres que han pecado de ser demasiado autoexplicativos.
Busca sustituirlos por otros que sean precisos y claros.
Tu yo del futuro lo agradecerá. 👨🏼💻👩🏼💻
Las palabras son pálidas sombras de nombres olvidados. Los nombres tienen poder, y las palabras también. Las palabras pueden hacer prender el fuego en la mente de los hombres. Las palabras pueden arrancarles lágrimas a los corazones más duros. Existen siete palabras que harán que una persona te ame. Existen diez palabras que minarán la más poderosa voluntad de un hombre. Pero una palabra no es más que la representación de un fuego. Un nombre es el fuego en sí.
El nombre del viento. Patrick Rothfuss