Uso de nombres que revelan intención
En el desarrollo de software es frecuente el uso de nombres para variables, métodos, clases y otros, por ello, el uso de nombres que revelan con qué fin se está utilizando es fundamental para mantener un código limpio, sencillo de entender y, por ende, de mantener.Si una variable, método o clase necesita un comentario para revelar su intención entonces se debería replantear el nombre de esa variable.
Evitar la desinformación
Se deben evitar nombres que no sean lo suficientemente explícitos. Las abreviaturas como tmp pueden llevar a confusión, ya que el lector podría entender que se trata de una variable temporal cuando en realidad es una variable que almacena temperatura (temperature).Tampoco se deberían usar nombres específicos del lenguaje de programación como por ejemplo usersArray. Con este nombre la variable da la impresión de almacenar un listado de usuarios en una estructura de tipo array. Si en un futuro, el tipo de estructura cambia y deja de ser un array para convertirse en una clase que gestiona un grupo de usuarios y el nombre no cambia va a generar confusión pues la variable sigue dando a entender que sigue siendo una estructura array que almacena usuarios. Un nombre más semántico que evite el tipo de implementación podría ser usersGroup o simplemente users.
Hacer distinciones significativas
En los casos en los que un buen nombre sea una palabra reservada del sistema, como por ejemplo class) no se deben usar nombres similares que tengan faltas de ortografía (klass), cambiar letras por números (cl4ss), añadir un número (class2) ni ninguna otra ingeniosa creatividad que solvente el problema.También deben evitarse las palabras sin sentido como pueden ser Data, Info, The, etc, que no añaden un significado concreto.
Las palabras que contienen significado para los programadores como pueden ser variable, table, string, Array,y Object, no deberían aparecer como parte de un buen nombre. Por ejemplo, NameString o NameObject no aportan un significado diferente a name.
Nombres que se puedan pronunciar
Un buen nombre debe poder pronunciarse y ser comprensible. Los nombres que son contracciones o partes de palabras no expresan adecuadamente el significado provocando confusión y no deben utilizarse.El nombre genymdhms no tiene un significado concreto pero si renombramos a generationDate un lector podrá entender que el nombre hace referencia a una fecha en la que se ha generado algo.
Nombres que se puedan buscar
Si los nombres se pueden buscar es mucho más fácil localizarlos entre el código. Los nombres formados por pocas letras o números siempre son más complicados de buscar.En general, los nombres más largos son mejores que los nombres más cortos y cualquier nombre es mejor que un número mágico en el código. Buscar el número mágico 7 en el código puede derivar en falsos positivos pero siempre será más fácil y eficaz encontrar el nombre de una constante como puede ser «const USER_STATUS_OK = 7». Además, nos resultará más fácil cambiarlo en todo el proyecto ya que sólo hay que modificarlo en un único sitio.
Evitar codificaciones
Al añadir más información al nombre de las variables se añade información extra que posteriormente supondrá un esfuerzo adicional para el programador que tendrá que descodificarla y mantenerla. Por ello, no es recomendable añadir información adicional a los nombres. Los nombres que usan estas codificaciones son raramente pronunciables lo que incumple la regla. Además si cambian su tipo sin renombrar la variable, esto genera confusión en el lector.Notación húngara
En la notación húngara se añade un prefijo a la variable para indicar su tipo. Antiguamente, los programadores lo usaban para recordar los tipos de variables cuando los compiladores no comprobaban los tipos de estas.En los nuevos lenguajes, los compiladores recuerdan y fuerzan los tipos. por lo que no es necesario el uso de esta notación.
Prefijos de miembro
No se necesita usar prefijos de miembro como «m_» ya que el tipo y la visibilidad de los mismos se deberían especificar mediante el propio lenguaje y con clases lo suficientemente pequeñas para que no haya dudas al respecto. Los IDE de desarrollo actuales usan colores para diferenciarlo.Interfaces e implementaciones
Las interfaces no deberían incluir el prefijo “I” ya que ofrece información a los usuarios sobre la implementación de la variable, en este caso, de esta interfaz. En los casos en los que haya que crear una factoría y esta factoría sea diseñe creando una interfaz (por ejemplo shapeFactory) la implementación es la que debería incluir la codificación (CShapeFactory).Evitar asignaciones mentales
Cuando un nombre no pertenece al dominio del problema ni al dominio de la solución el lector deberá inferir la intención de dicho nombre a medida que vaya comprendiendo el código. De esta forma, el lector habrá de realizar una asignación mental de ese nombre con la intención.Por ejemplo, al usar la letra «u» para referirse a una URL, el lector del código tendrá que hacer una asignación mental de «u» con una URL.
Nombres de clases
Las clases deberían tener por nombre sustantivos o frases de sustantivos pero nunca un verbo. Las palabras Manager, Processor, Data or Info no aportan un significado concreto y deberían evitarse.Ejemplos: user, post, comment, etc.
Nombres de métodos
Los métodos son acciones que se producen en el objeto por ello siempre deberían ser verbos o frases con verbos.Ejemplos: save, update, delete, load, isConfirmed, isPublished, etc.
Cuando los constructores están sobrecargados se aconseja usar métodos estáticos a modo de factoría con nombres que describan los argumentos del mismo. Haciendo el constructor privado se consigue forzar a usar estos métodos factoría.
Por ejemplo:
Point $point = new Point(12, 3);
Point $point = Point::createFromText(“12,3”);
Point $point = Point::createFromXAndY(12,3);
La primera instrucción crea una instancia de la clase Point con un constructor y dos parámetros. La segunda instrucción crea otra instancia desde un método estático de la clase y usa un parámetro de tipo string. La tercera instrucción crea otra instancia desde otro método estático a partir de dos valores como el primer método.
No excederse con las personalizaciones
Si los nombres son producto de alguna broma o gracia del momento esta sólo tendrá sentido para aquellos que la conozcan. Si un programador se encuentra en la clase user con un método FinishHim (a lo Mortal Kombat), cuyo fin es borrar un usuario, lo más probable es que no sepa lo que hace hasta que no haya investigado ese método. El nombre delete es un nombre más semántico que todo el mundo puede entender.Elegir una palabra por concepto
A veces aparecen varios nombres para el mismo concepto como puede ser get, fetch, retrieve. Unificar en una palabra un mismo concepto ayuda a entender el código ya que palabras diferentes podrían tener funcionamientos diferentes. Por ello, es recomendable elegir una palabra y seguir esa directriz.No hacer juegos de palabras
Siguiendo la regla anterior se debe evitar usar la misma palabra para dos conceptos diferentes. Se considera un juego de palabras usar una palabra para referirse a dos conceptos distintos a pesar de ser semánticamente correcto. En estos casos hay que elegir un nombre diferente.Si tenemos varias clases que tienen una función add la cual suma un valor a un atributo, la elección del nombre sería semánticamente correcta y el concepto sería el mismo en todas las clases. Si surge la necesidad de añadir un elemento a una lista aunque semánticamente add es correcto, se estaría utilizando para dos conceptos distintos: sumar y añadir a una lista. En consecuencia, para distinguir los conceptos, habría que usar otra palabra como podría ser append, insert, push.
Usar el nombre del dominio de soluciones
El código debería estar escrito para otros programadores por lo que al utilizar términos del ámbito de la programación como nombres de algoritmos, patrones de diseño, FIFO, Queue, etc, se facilita la transmisión de la intención del autor.Usar el nombre del dominio de problemas
En los casos en los que no haya un término técnico o un nombre del dominio de soluciones se recomienda usar nombres del dominio de problemas ya que por lo menos habrá un experto al cual preguntar sobre el término.Añadir un contexto con significado
La mayoría de las veces los nombres no tienen un significado por si sólo por lo que hay que englobarlos en un contexto donde esté bien nombrado y tenga un significado semántico acorde a lo que se quiere expresar.En los casos en los que esto no se puede o no queda claro se puede añadir un prefijo. Por ejemplo, si vemos una variable state, a priori, no sabemos si es parte de una dirección o de otro concepto. Añadiendo el prefijo addr el nombre quedaría como addrState y, de esta manera, podría inferirse que es parte de una dirección.
Aunque la mejor solución sería crear una clase Address y que state fuera un atributo, con lo que quedaría definido como parte de una dirección.
No añadir contextos gratuitos
No es una buena práctica añadir contextos que no aportan valor. Por ejemplo, si tenemos un blog llamado eltortuganegra.com no aportaría nada añadir el prefijo ETN a los nombres del sistema. Por ejemplo, ETNUser o ETNPost no aportan ningún valor específico y complican la comprensión de la justificación de dicho prefijo.Conclusiones
Una buena elección de nombres depende de la habilidad descriptiva del programador y del trasfondo cultural que comparta con el resto de programadores.No es usual que, una vez desarrollado el código, haya un cambio en los nombres, aunque esto no debería ser excusa para no elegir nombres adecuados.
Bibliografía
Clean Code de Robert C. Martin