Artículos

¿Qué es el código limpio y por qué es crucial para desarrollar software de calidad?

Muchos desarrolladores han oído hablar del código limpio o incluso lo usan todos los días, a veces sin saber demasiado sobre él. En esta publicación explicaremos qué es el código limpio, por qué debe usarse y por qué es un buen hábito para incorporar. Si ya conoces el código limpio, este artículo te ayudará a repasar los conceptos principales; si la idea es nueva para ti, al terminar comprenderás los beneficios de escribir código limpio y aprenderás cómo hacerlo.

¿Qué es el código limpio?

Antes de profundizar en el código limpio, debemos mencionar a Robert C. Martin (conocido como Uncle Bob), un reconocido ingeniero de software, coautor del Manifiesto Ágil y colaborador en el desarrollo de los principios SOLID. Uncle Bob es el autor de Clean Code: A Handbook of Agile Software Craftsmanship, un libro muy influyente que cambió la forma de escribir código.

Clean Code es una guía para escribir código elegante, eficiente y fácil de leer. Abordaremos las pautas más importantes, pero también recomendamos leer el libro, ya que cubre más temas y con mayor profundidad de lo que podemos hacer en esta publicación.

Nombres, comentarios y formato

Puede parecer trivial, pero los nombres, los comentarios y el formato son aspectos importantes que permiten que cualquier desarrollador lea y comprenda el código con mayor facilidad.

Al declarar nuevos atributos, funciones o métodos, el nombre desempeña un papel clave. Elegir un nombre significativo que se explique por sí mismo mejora nuestro código. Debemos evitar nombres difíciles de leer, que no signifiquen nada o que no sean relevantes para el propósito del atributo, la función o el método. Elegir el nombre correcto también facilita buscar y localizar esos nombres en el código.

Si elegimos bien los nombres, deberíamos evitar la necesidad de usar comentarios. Deben evitarse si es posible, ya que pueden ser perjudiciales cuando no se usan correctamente. Los comentarios son difíciles de mantener porque, si cambia el código, hay que actualizarlos manualmente. Si no se actualizan, pueden generar confusión y problemas innecesarios. Se pueden hacer comentarios informativos, legales o aclaratorios si ayudan a que el código sea más legible, pero, como regla general, deben usarse lo menos posible. Si el código es limpio, no serán necesarios.

Dar formato al código puede parecer poco importante, pero es un aspecto clave para crear código profesional y legible. Los archivos deben tener una cantidad máxima de líneas de código, y cada archivo no debería superar las 500 líneas si es posible. Además, el código debe tener un máximo de 100 a 120 caracteres en sentido horizontal. Como se lee de arriba abajo y de izquierda a derecha, debe tener sangría según las convenciones de orden jerárquico.

Funciones

Una de las reglas más importantes al crear funciones es que sean pequeñas. Las funciones largas son difíciles de leer y entender, por lo que debemos mantenerlas simples y cortas. Si tenemos una función de más de 20 líneas de código, debemos intentar dividirla en varias funciones más cortas y fáciles de leer.

Otro aspecto clave es que las funciones deben hacer una sola cosa. Hay distintas maneras de saber si una función hace solo una cosa, pero, como regla general, si tiene más de un nivel de abstracción, hace más de una cosa. Debemos mantenerla en un solo nivel de abstracción y evitar mezclar niveles dentro de la función.

Hay muchos otros aspectos que debemos considerar al escribir funciones, como la cantidad de argumentos que deben usar. Al planificar una función, debemos tener en cuenta que no se deben usar más de tres argumentos. Idealmente, este número debe acercarse lo más posible a cero, ya que esto reduce la complejidad de las funciones y facilita las pruebas. Menos argumentos implican menos pruebas, porque hay menos combinaciones que probar. Por último, las funciones deben hacer lo que se supone que deben hacer; puede sonar redundante, pero es importante asegurarse de que usar una función no tenga efectos secundarios no deseados ni comportamientos inesperados.

Objetos y estructuras de datos

Un aspecto clave del código limpio es ocultar la implementación detrás de la abstracción. Al crear clases, debemos intentar ocultar la implementación mediante interfaces abstractas para evitar dependencias entre secciones del código. Usar métodos getter y setter para obtener variables directamente de las clases no es una buena idea. En su lugar deben usarse interfaces, que permitan manipular estos datos independientemente de la implementación de esas clases. Esto nos evitará problemas innecesarios cuando una clase necesite una nueva implementación.

Ahora que hemos ocultado nuestra implementación, podemos cumplir la ley de Demeter. Esta ley establece que los módulos no deben conocer la estructura interna de los objetos que manipulan. Como regla general, los objetos deben exponer comportamiento y ocultar datos; por el contrario, las estructuras de datos deben exponer datos y no tener un comportamiento significativo.

Manejo de errores y pruebas

El enfoque del código limpio para manejar errores implica usar excepciones para capturarlos en lugar de devolver errores o indicadores. Por ejemplo, es una buena práctica usar try-catch en las secciones del código que podrían fallar y capturar los errores correctamente. Para la depuración y un mejor manejo de errores, es importante crear mensajes de error usados por las excepciones, de modo que, cuando ocurra un error, se proporcione información suficiente para identificar su origen.

Las pruebas son una parte importante del código limpio, y escribir pruebas adecuadas es fundamental. Si es posible, se recomienda usar la técnica de programación TDD para garantizar una cobertura de pruebas de casi el 100%. Las pruebas deben mantenerse para que no se desarrollen por separado del sistema. Si cambia el código, debe actualizarse la prueba.

Al escribir pruebas, hay cinco reglas que debemos seguir para garantizar pruebas adecuadas y limpias: rápidas, aisladas, repetibles, que se autovaliden y oportunas (F.I.R.S.T). Como las pruebas deben ejecutarse continuamente durante la programación o de forma automática después de escribir el código, deben ser rápidas. Si son lentas, los desarrolladores pueden evitar ejecutarlas porque tardan demasiado. Esto provoca problemas futuros y malas prácticas.

Al crear una prueba, debemos tener en cuenta que cada una debe ser independiente; ninguna debe depender de otra para poder ejecutarse. Las pruebas deben ejecutarse en todos los entornos, como desarrollo o producción. Si una prueba se ejecuta en desarrollo pero no puede ejecutarse en producción, esto conducirá a malas prácticas. El resultado debe ser fácil de leer. La mejor práctica es devolver un booleano que indique el resultado de la prueba, ya que permitirá a los desarrolladores obtenerlo rápidamente. Por último, es una buena práctica planificar y escribir las pruebas antes de que el código real llegue a producción.

Clases

Al planificar e implementar clases, necesitamos un enfoque similar al de las funciones. Las clases deben ser pequeñas y es importante que el nombre sea significativo, ya que pueden usarse en todo el sistema. Deben seguir el principio de responsabilidad única (SRP). Para cumplirlo, las clases deben tener una sola responsabilidad y una sola razón para cambiar. Si una clase tiene muchas responsabilidades, es una buena práctica dividirla en clases separadas.

¿Por qué debemos usar código limpio?

Después de analizar el código limpio, podemos ver que usarlo tiene varios beneficios. Repasaremos los más importantes de aplicar sus principios al escribir código.

Costo

El costo de implementar un sistema puede ser un asunto clave al conseguir nuevos proyectos o clientes. Es importante ajustarse a las estimaciones de costos para evitar problemas innecesarios con los clientes. Los desarrolladores o responsables saben que el costo de corregir problemas o errores crece exponencialmente a medida que el código avanza por las distintas etapas de desarrollo. Seguir las prácticas de código limpio nos ayudará a evitar este problema mediante pruebas unitarias, pruebas creadas siguiendo F.I.R.S.T, el uso de TDD, etc.

Tiempo

Para los desarrolladores puede ser difícil trabajar con proyectos o código que no escribieron o en los que no participaron. Imagina que acabas de incorporarte a un proyecto y tienes que desarrollar una nueva funcionalidad o corregir un error en un sistema. Si el código es difícil de leer, no tiene sangrías y los nombres de las clases o métodos no significan nada, tendrás que invertir más tiempo del habitual en comprender el código de este nuevo sistema. Si el código sigue las pautas de código limpio, será fácil de leer y los desarrolladores tardarán menos en entenderlo, implementar nuevas funcionalidades o corregir errores adecuadamente.

Facilidad de mantenimiento

El proceso de desarrollo no termina cuando un sistema llega a producción. Debemos invertir una cantidad importante de tiempo y esfuerzo para mantenerlo actualizado y permitir que funcione correctamente y con eficiencia. Si el código del sistema es un desastre, nos resultará difícil detectar qué secciones deben actualizarse o qué dependencias están obsoletas.

Capacidad de adaptación

Los sistemas no son estáticos y, a medida que cambia el negocio o el contexto, deben poder adaptarse a esos cambios y seguir siendo relevantes para los usuarios. Debemos asegurarnos de que el sistema que construimos pueda cambiar, porque el cambio es inevitable y debemos manejar su impacto. Si seguimos las pautas de código limpio sobre cómo implementar clases, estructuras de datos y objetos, evitaremos trabajo innecesario al cambiar o actualizar secciones completas del sistema.

Calidad

Muchos de los aspectos mencionados determinarán si nuestro sistema cumple los estándares de calidad del desarrollo de software. Por eso el código limpio se ha convertido en un indicador de calidad para los desarrolladores: ayuda a desarrollar mejores sistemas.

Convertir el código limpio en un hábito

Hemos visto que usar prácticas de código limpio beneficia tu forma de escribir código, pero ¿cómo puedes convertir estas pautas en un hábito e incorporarlas a tus habilidades? Lo primero es saber que el código limpio no se domina en un día: necesitarás tiempo para practicar y convertir estos conceptos en un hábito.

Como hay muchos aspectos que considerar, recomendamos algunos consejos. Primero, haz una pequeña lista con todos los conceptos clave, como nombres, comentarios, funciones, etc. Tenla a mano mientras escribes código, para revisar los elementos a medida que programas. Por ejemplo, después de escribir una función, puedes revisar rápidamente su nombre, tamaño, si hace una sola cosa, etc. Además, después de crear una pull request puedes revisar todo el código para verificar que sigues estas pautas. Después de un tiempo, no necesitarás tener la lista a mano y empezarás a programar siguiendo estas pautas sin tener que recordártelo.

Reflexiones finales

Los desarrolladores de sophilabs usamos las pautas de código limpio para escribir nuestro código diariamente. Este es uno de los aspectos clave que revisamos cuando un desarrollador crea una pull request. Según nuestra experiencia, consideramos estas pautas la mejor forma de escribir el mejor código posible. Es bastante común que nuevos desarrolladores se incorporen al equipo. Su proceso de incorporación puede ser muy desafiante, ya que deben aprender cómo funcionan todos los sistemas. Sin embargo, el código limpio les permite comprender el código lo más rápido posible y empezar a entregar valor al cliente antes.

Escribir código no solo implica hacer algo que funcione y cumpla las expectativas, sino hacerlo de la mejor manera posible. Con código limpio, los desarrolladores pueden crear sistemas fáciles de mantener, capaces de adaptarse a los cambios, que mejoren su rendimiento y eviten el desperdicio de recursos. Incorporar el código limpio como hábito es una decisión que nos hace mejores desarrolladores.

“¿Qué es el código limpio y por qué es crucial para desarrollar software de calidad?” de Facundo Revello está bajo la licencia CC BY SA. Los ejemplos de código fuente están bajo la licencia MIT.

Foto de Émile Perron.

Clasificado en Investigación y aprendizaje.

Lecturas relacionadas