Clean Code en Dart — Nombres significativos — Parte 1
Introducción
La elección de un buen nombre, que demuestre una verdadera intención, evite la desinformación y logre evitar los mapas mentales durante la lectura del código, es una de muchas buenas prácticas para que el código sea considerado de buena calidad. No es fácil llegar a escribir un código limpio, no todos aprendemos a programar de la misma manera, algunos comienzan con un buen mentor, libro, u otro método, sin embargo hay quienes tienen otras realidades totalmente distintas, pero en algún momento todos debemos aprender y aplicar las buenas prácticas de un código limpio para ser considerado un buen programador.
Algunos expertos consideran que un buen programador es aquel que escribe código limpio, testea su código y un sin fin de buenas prácticas que iremos abordando en esta serie. El motivo principal por el que escribo esta serie es para que logremos ser mejores programadores, ya que esto nos beneficia a todos.
Los ejemplos que verás en esta serie están programados en el Lenguaje de programación Dart y otros ejemplos en el Flutter.
1. Utiliza nombres que demuestren intenciones
Elegir buenos nombres puede resultar una tarea compleja si no se comprende en su totalidad la solución que se está brindando a un problema del negocio. El nombre de una variable, clase, función, etc., debiera responder idealmente a estas tres preguntas:
- ¿Por qué existe?
- ¿Cuál es su función?
- ¿Cómo es usado?
Si el nombre que has seleccionado requiere de un comentario para explicar la intención de este, entonces no es la mejor opción, por el simple hecho que estás agregando código innecesario y, por ende, más lineas de código, siendo que podría quedar clara la intención de una variable escogiendo un buen nombre.
Veamos un ejemplo de una “mala” elección de nombre para una variable:
class BadExample {
int d; // Tiempo transcurrido en días.
String cd; // Día actual;
}
¿Por qué es un “mal” nombre?
Primero que todo, el nombre “d” y “cd” no revelan ninguna intención, no evoca la sensación de tiempo transcurrido, ni tampoco el día actual. Además, se está utilizando un comentario para explicar la real intención de este, doble error.
Ahora veamos una “buena” elección para los casos anteriores:
class GoodExample {
int elapsedTimeInDays;
String currentDay;
}
¿Por qué es un “buen” nombre?
En comparación al primer caso, estos nombres de variables sí expresan una intención al momento de leerlos, y no se necesita un comentario para explicar su función.
2. Evita la desinformación
Los programadores debemos evitar las palabras cuyos significados arraigados difieran del significado pretendido.
Veamos algunos ejemplos de variables deficientes:
- hp
- aix
- sco
¿Por qué son deficientes? Además de no mostrar una intención clara, estos nombre de variables son nombres de plataformas o variantes de Unix.
Otro ejemplo práctico, y que se podría considerar como desinformación, es cuando nos referimos a una agrupación de cuentas con el nombre de accountList. ¿Por qué? Se considera desinformativa porque la palabra List significa algo específico para los programadores, es un tipo de dato, entonces se puede dar el caso que esta agrupación de cuentas no es realmente una lista, y esto puede llevar a conclusiones falsas.
Para el caso mencionado anteriormente, algunas opciones de nombres correctos podrían ser:
- accounts
- accountGroup
3. Realiza distinciones significativas
Muchas veces los programadores cometemos el error de crear intencionalmente, o sin darnos cuenta, palabras “ruidosas”, es decir, palabras sin sentido.
¿Cómo podemos identificar las palabras “ruidosas”?
Veamos un ejemplo para entender de mejor manera las palabras ruidosas. Supongamos que tenemos una clase llamada Product:
class Product { ... }
Todo bien hasta aquí, este nombre es ideal para representar una entidad de un producto x, sin embargo, el problema aparece cuando creamos una nueva clase llamada ProductInfo o ProductData
class ProductInfo { ... }class ProductData { ... }
¿Por qué?, porque hemos hecho que los nombres sean diferentes sin que signifiquen nada diferente. Las palabras Info y Data son palabras irrelevantes indistintas.
Las palabras “ruidosas” son redundantes, otros ejemplos podrían ser:
- La palabra variable nunca debe aparecer en un nombre de variable.
- La palabra tabla nunca debe aparecer en el nombre de una tabla.
- La palabra accountData es indistinguible de Account.
4. Utiliza nombres pronunciables
A pesar que este artículo está redactado en español, los ejemplos que hemos descrito se escriben en inglés debido a que siempre es recomendable programar en este idioma, considerando que el largo de las palabras es menor en comparación al español, y toda la documentación se encuentra principalmente en este idioma.
Siempre es recomendable utilizar nombres que sean pronunciables en la vida cotidiana, ya que esto ayuda a que la lectura del código sea mucho más natural.
Veamos algunos ejemplos de nombres impronunciables:
class DtaRcrd102 {
DateTime genymdhms;
DateTime modymdhms;
String pszqint = "102"; /* ... */
}
Difícil de pronunciar, ¿cierto?. Veamos un ejemplo con nombres pronunciables:
class Customer {
DateTime generationTimestamp;
DateTime modificationTimestamp;
String recordId = "102"; /* ... */
}
5. Utiliza nombres que sean fáciles de buscar
Aunque no lo creas, utilizar nombres que sean fáciles de rastrear por nuestro IDE nos ahorra bastante tiempo para realizar cambios específicos o agregar nuevas funcionalidades a nuestro código.
Veamos primero, ¿cuáles NO son palabras fáciles de buscar?
Las palabras que no son fáciles de buscar, son las que poseen una sola letra o constantes numéricas.
// Palabras de una sola letra
String a;// Constantes numéricas (7)
for (int i = 0; i < 7; i++) { ... }
¿Programas todo tu código en Inglés?
Tienes un pequeño problema adicional, las palabras que empiezan con la letra “e” también suelen ser una “mala” elección, ¿por qué?, la mayoría de las palabras en ingles comienzan con esta letra y dificulta su búsqueda.
Entonces, ¿cuál sería un buen nombre para realizar una búsqueda de manera eficiente?
Martin (2009) recomienda utilizar nombres de una sola letra solo cuando se ocupan como variables locales dentro de un método suficientemente pequeño.
Para el caso de las constantes numéricas, una buena práctica puede ser definirlas de la siguiente forma:
static const int MAX_CLASSES_PER_STUDENT = 7;
Veamos un ejemplo para caso de una búsqueda compleja:
for (int i = 0; i < 10; i++) {
s += (t[i]*4)/5;
}
Difícil de rastrear si tenemos nombres de una sola letra y constantes sin definir. Veamos el mismo caso pero con una buena implementación:
int realDaysPerIdealDay = 4;
static const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;for (int i = 0; i < NUMBER_OF_TASKS; i++) {
int realTaskDays = taskEstimate[i] * realDaysPerIdealDay;
int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK);
sum += realTaskWeeks;
}
¿Notas la diferencia?, este último código es mucho más legible y, además, mucho más fácil de rastrear que el primer caso.
6. Nombres de Clases y Métodos
Finalmente, elegir un buen nombre de Clase o Función, nos permitirá una mejor lectura de nuestro código, es por esto que te dejo algunos consejos para ambos:
Clases
Las clases deben tener nombres sustantivos o frases sustantivas por ejemplo:
- Customer
- Account
Deben evitar las palabras ruidosas, como: Manager, Processor, Data o Info y nunca el nombre de una clase debe ser un verbo.
Métodos
Los métodos, por otro lado, sí deben tener nombres de verbos o frases verbales, por ejemplo:
- postPayment
- deletePage
- save
Los accesadores y mutadores deben tener el nombre de su valor y el prefijo get o set, por ejemplo:
final String name = employee.getName();customer.setName("Favaz");
Conclusión
Desde el comienzo, y sobre todo en la actualidad, escribir código limpio es una de las cualidades fundamentales que un buen programador debe manejar, es más, si no tenemos un código limpio, no seremos considerados buenos programadores.
Información adicional
- Puedes revisar más contenido de código limpio con ejemplos prácticos en Dart o Flutter en mi canal de YouTube.
- Puedes revisar la segunda parte de esta serie acá — Parte 2.
Referencias
Martin, R. (2009). Clean Code: A Handbook of Agile Software Craftsmanship. Prentice Hall.