Código limpio con comentarios útiles

Un código con buenos comentarios ayuda a su legibilidad como vimos en el artículo sobre cómo escribir código limpio y legible.

Cada bloque de código tiene un propósito, puede recibir parámetros y puede devolver un resultado. Toda esta información debería estar explicada brevemente en un bloque comentado, preferentemente antes de los bloques de ejecución. Por ejemplo:

// Función calculaPrecioFinalDeCarrito

//    Calcula el precio final del carrito ajustando impuestos y conversión de moneda

//

// Entrada:

//    lista de productos, tipo de impuestos, tipo de moneda

// Salida:

//    precio final a pagar por el cliente

function calculaPrecioFinalDeCarrito(listaProductos, tipoDeImpuestos, tipoMoneda) {

    var precioSinImpuestos = calculaPrecioDeListaDeProductos(listaProductos)

    var precioConImpuestos = calculaImpuestos(precioSinImpuestos, tipoDeImpuestos)

    var precioFinal = convierteAMoneda(precioConImpuestos, tipoMoneda)

    return precioFinal

}

Pero se debe ser breve y evitar comentar todo lo que hace el código línea a línea explicando sólo lo esencial.

Se debe explicar el porqué de las cosas y no cómo se hacen. Un buen código se da a entender por sí solo y no necesita extensos comentarios para ello.

Consistencia y legibilidad para un código limpio

En el artículo sobre cómo escribir código limpio y legible hablamos de la necesidad de coherencia cuando escribimos código.

Legibilidad por encima de la simplicidad

Algunos lenguajes de programación permiten realizar varias operaciones en una sola línea de código. Por ejemplo en Swift, Java o C++ podemos crear una instancia de clase, llamar a uno de sus métodos y realizar una comparación dependiendo del resultado de esa llamada todo en una sola línea de código. Esto reduce el número de líneas que pueda tener una función pero no mejora la legibilidad del código ya que quizás esas características del lenguaje de programación no son conocidas por todos los programadores.

Recuerda escribir el código para que lo pueda leer otra persona, porque incluso hay altas probabilidades que esa otra persona seas tú y puede que no entiendas tu propio código pasado unos meses o años.

Consistencia en la arquitectura de un proyecto

Una de las decisiones principales a tomar cuando empezamos un proyecto software es la de qué patrón de diseño utilizaremos para la arquitectura de nuestra aplicación.

Una vez tomada esta decisión debemos evitar mezclar arquitecturas ya que aumentamos la complejidad a la hora de entender cómo se organiza nuestro proyecto.

Código limpio sin código inutil

En el artículo sobre cómo escribir código limpio y legible hablamos de la necesidad de un código que no tenga bloques de código inútil.

Estos bloques de código inútil se originan normalmente cuando estamos probando un código de forma temporal para hacer un experimento en nuestro proyecto.

Activando y desactivando bloques de código

Dentro de un proyecto de software puede que durante una ejecución de prueba controlada nos interese desactivar un bloque de código y activar otro. Esto se consigue gracias a las instrucciones para añadir comentarios en un código.

Cada lenguaje de programación posee uno o varios métodos para comentar un trozo de código. Por ejemplo la función original sería:

Funcion calcularImpuesto() {

    calcularImpuestosDelCarrito()

}

Y para nuestro experimento quedaría así:

Funcion calcularImpuesto() {

    // Comentamos la siguiente línea para la prueba

    // calcularImpuestosDelCarrito()

    // Usamos el experimento

    calcularImpuestosDelCarritoDeOtraForma()

}

El problema

El problema aparece cuando dejamos esos comentarios porque nos ha gustado más el resultado de la prueba. El código resultante está lleno de bloques inútiles que dificultan la lectura del código.

La solución consiste en quitar esos bloques de código y dejar sólo el código útil. El ejemplo quedaría al final así:

Funcion calcularImpuesto() {

    calcularImpuestosDelCarritoDeOtraForma()

}

¿Cómo no perder esos bloques comentados?

Puede que para nuestro proyecto nos interese no perder ese código alternativo que al principio estaba desactivado con comentarios y que posteriormente borramos para mejorar la limpieza de nuestro código.

Para evitar perder este código alternativo lo mejor es utilizar un sistema de gestión de versiones de código como Git o Mercurial.

Con estas herramientas podemos tener varias versiones de nuestro proyecto e ir manteniendo el código límpio en todo momento sin perder nada ya que con la herramienta de gestión de versiones podemos consultar código más viejo en cualquier momento.

Funciones simples para un código limpio

En el artículo sobre cómo escribir un código limpio y legible hablamos de la necesidad de escribir funciones simples y cortas.

Esto se debe a que a la hora de leer código de otra persona si una función es demasiado larga y posee muchas líneas de código es muy probable que perdamos el foco de atención. Además eso puede significar que la función está realizando demasiadas tareas y debemos atomizar nuestro código.

Código atomizado

Una función con código atomizado tiene un propósito y no puede reducirse o simplificarse mas. Cuanto más simple sea nuestra función más claro será nuestro código.

Por ejemplo una función llamada calcularAlmacenajeDeSucursales puede dividirse en varias funciones más pequeñas que calculen el resultado que estamos buscando en nuestra función inicial.

Dividiendo una función en varias funciones más pequeñas conseguimos atomizar nuestro código y mejorar su legibilidad.

Nombres claros para un código limpio

Como vimos en el artículo sobre cómo escribir código limpio y legible el utilizar nombres claros y explícitos para nombrar variables, constantes, funciones y clases es indispensable para considerar que tenemos un código limpio y legible.

Variables y constantes

A la hora de poner nombre a una variable o constante debemos pensar en que nuestro código lo puede leer otra persona y tendrá qué entender que hace nuestro código. Una variable llamada aux, A, contar o num no aclara qué hace un código pero nombres como hipotenusa, precioFinal, distanciaDelMargen o ContadorDePalabras si son nombres más comprensibles para todos.

Funciones y clases

A la hora de poner nombres a métodos y clases debemos prestar atención al trabajo o responsabilidad que realizan. Nombres de clases como ControlDeDatosDeUsuario, VisualizadorDeDatosDeUsuario, DriverDeDatosDeUsuario son nombres apropiados para entender qué hace una clse.

En el caso de las funciones o métodos el nombre debería describir la función que se va a realizar. Nombres como GuardarDatosDeUsuario, CargaDatosDeUsuario o BorraUsuario son nombres bastante explícitos para entender qué hará la función al ser llamada.

Coherencia a la hora de escribir los nombres.

Hay varios métodos para escribir nombres de variables, métodos y clases como el método Camel case, el Pascal case o la notación Húngara.Podemos seguir cualquiera de estos métodos de escritura de nombres pero lo que no debemos hacer es mezclarlos en un mismo proyecto ya que hace que nuestro código sea confuso de entender y mantener.

Cómo indentar el código para que sea limpio y legible

Como vimos en el artículo sobre cómo escribir código limpio y legible una de las características es la de que el código esté escrito con una buena indentación.

¿Qué es la indentación de un texto?

La palabra indentación, como otras muchas palabras tecnológicas, proviene de una traducción libre del término indentation. En castellano el término correcto sería espacio de sangrado para un texto.

En pocas palabras es el espacio vacío situado a la izquierda de una línea de texto.

En un bloque de texto con varias líneas podemos tener distintos niveles de sangrado. Cuando esto ocurre esa diferencia de espacios vacíos a la izquierda empieza a tener significado ya que visualmente nos permite identificar las diferencias entre una línea y la siguiente.

En el caso de algunos lenguajes de programación como Python o el lenguaje de formateado de datos YAML el nivel de indentación tiene un significado claro ya que se utiliza para indicar el comienzo de un bloque o dominio.

En otros lenguajes el nivel de indentación se utiliza para identificar fácilmente si una línea de código pertenece a un bloque condicional, una función o bloque de código. De esta forma podemos encontrar visualmente cuándo comienza y termina una función o un conjunto de instrucciones que pertenecen a un mismo bloque de código.

¿Espacio o tabulación?

Dentro del mundo de la programación hay personas que prefieren utilizar el caracter de espacio para indentar el código y otras personas prefieren el caracter de tabulación. Esto honestamente no tiene demasiada importancia siempre y cuando no mezclemos tabulaciones con espacios y seamos coherentes con nuestra forma de indentar el código.

Además los editores de código más habituales nos permiten seleccionar entre espacio o tabulación para indentar nuestro código.

Indentación y accesibilidad

La indentación del código puede resultar invisible a programadores ciegos que utilicen el lector de pantallas mediante una síntesis de voz. Utilizando una línea braille o braille display el nivel de indentación es visible gracias a que los caracteres en blanco son legibles a través del dispositivo de lectura braille.

Para facilitar la tarea de identificar el nivel de indentación de una línea para los usuarios de lectores de pantalla con voz se incluyen características en estos productos de apoyo para identificar el nivel de indentación de una línea de textos. Tanto JAWS, NVDA como ORCA incluyen opciones para activar la identificación del nivel de indentación de un texto. Incluso permiten activar un modo para que el lector de pantallas avise al usuario de que el nivel de indentación ha cambiado cuando sube o baja por el fichero de código.

En el caso de VoiceOver para MacOS esta opción no está disponible por defecto pero podemos utilizar un AppleScript para saber el nivel de indentación de un texto.