Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Refactorización y Documentación
Contenidos
1. Clean
Code: código
limpio, ¿qué es?
Seguro que alguna
vez programando o
analizando programas,
has visto un código
mal hecho o con un
título que no
correspondía de
verdad a su función.
Este escenario es más
común de lo que te
puedes imaginar y es
justamente el que
Clean Code busca
combatir.
Clean Code, o Código Limpio, es una filosofía de desarrollo de software que consiste en
aplicar técnicas simples que facilitan la escritura y lectura de un código, volviéndolo más
fácil de entender.
¿Cuándo surgió el término Clean Code?
Las técnicas de código limpio aparecieron por primera vez en el libro “Clean Code: A
Handbook of Agile Software Craftsmanship”, lanzado en 2008. Este fue escrito por Robert
Cecil Martin, conocido en la comunidad como Uncle Bob. El autor trabaja con desarrollo y
programación desde 1970 y es uno de los profesionales que lideró el Manifiesto Ágil, en
2001.
Con sus largos años de experiencia, Bob encontró que el problema principal en el desarrollo
de software era precisamente el mantenimiento. Es decir, un código mal escrito en su
primera versión puede funcionar, pero va a generar grandes problemas en el futuro.
Podemos decir entonces que además de tener buena arquitectura y buenas prácticas, el
código fuente (código principal, que hace que el computador ejecute nuestros comandos)
necesita de principios; y esta es la propuesta que Clean Code presenta.
Uno de los principales errores que los programadores cometen es creer que, una vez que el
código esté listo y funcionando, no necesita de revisiones.
Es importante tener en cuenta que un sistema nunca está totalmente finalizado, pues
siempre existe la necesidad de realizar actualizaciones y nuevas funcionalidades. Además
de esto, el código envejece, y Clean Code encaja perfectamente en esta situación.
Un código con muchos ajustes durante mucho tiempo, se vuelve imposible de mantener, por
lo que es mejor crear un código nuevo y no continuar con una versión problemática.
Un código limpio evita gastos innecesarios y prepara al software para las actualizaciones y
mejoras.
Las 7 reglas principales del Clean Code
○ Variable;
○ Función;
○ Parámetro;
○ Clase;
○ Método.
Existe un principio que afirma que, si sales del área en que estas acampando, debes
dejarla más limpia que cuando la encontraste.
El ser humano está acostumbrado a pensar de manera narrativa, así que el código
funciona de la misma forma. Éste es una historia y, como los programadores son sus
autores, deben preocuparse por el modo en el que este cuento será presentado.
El tamaño de las funciones debe ser tal que hagan una sola cosa.
Para asegurarnos que nuestras funciones hacen una sola cosa, tenemos que
asegurarnos que de las sentencias dentro de nuestra función están al mismo nivel
de abstracción, lo que significa que deben estar en el mismo nivel de detalle y
enfocarse en la misma tarea específica. Por lo tanto, una buena práctica es separar
las tareas en funciones más pequeñas y especializadas que se encarguen de una
tarea específica cada una, y que sean llamadas en secuencia por una función de
más alto nivel que coordine las tareas más complejas. De esta manera, se puede
asegurar que cada función se enfoca en una tarea específica y que todas las
sentencias dentro de ellas están al mismo nivel de abstracción, lo que facilita su
comprensión y mantenimiento.
Veamos un ejemplo:
Este principio puede ser traducido como “no te repitas a ti mismo”. Una expresión,
que fue descrita por primera vez en un libro llamado The Pragmatic Programmer y
se aplica a áreas de desarrollo, como:
○ Bases de datos
○ Tests
○ Documentaciones
○ Codificaciones
DRY defiende que cada parte del conocimiento de un sistema debe tener
representación única y estar totalmente libre de ambigüedades. En otras palabras,
define que no pueden existir dos partes del programa que realicen la misma función.
El código debe ser conciso, modular y reutilizable, de modo que no tengamos que
repetir la misma lógica en diferentes partes del programa.
Cuando se repite el código en diferentes partes del programa, esto puede hacer que
el código sea más difícil de mantener y aumentar la posibilidad de errores, ya que
cualquier cambio en una parte del código tendría que ser replicado en todas las
demás partes. Además, la repetición de código también puede aumentar el tamaño
del programa, lo que puede afectar negativamente su rendimiento.
Para aplicar la técnica DRY en Clean Code, se recomienda seguir las siguientes
prácticas:
Este principio afirma que los comentarios pueden hacerse; sin embargo, estos
deben ser necesarios. Según Uncle Bob, los comentarios mienten; y esto tiene una
explicación lógica.
Lo que ocurre es que, mientras los códigos son modificados, los comentarios no.
Estos son olvidados, y por lo tanto, no retratan la funcionalidad real de los códigos.
6. Tratamiento de errores
Hay una frase del autor Michael Feathers, bastante conocida en el área de
desarrollo web, que afirma que las cosas pueden salir mal; pero cuando esto ocurre,
los programadores son los responsables por garantizar que el código continúe
realizando lo que necesita.
En Clean Code, se proponen varias prácticas para manejar los errores de manera
efectiva y clara:
7. Tests limpios
○ Fast: El test debe ser rápido, permitiendo que sea realizado muchísimas
veces y en cualquier momento;
○ Independent: Debe ser independiente, con el fin de evitar que cause efecto
cascada cuando ocurra alguna falla, lo que dificulta el análisis de los
problemas;
○ Repeatable: Debe permitir la repetición del test, muchísimas veces y en
diferentes ambientes;
○ Self-Validation: Los tests bien escritos retornan con las respuestas true o
false para que el error no sea subjetivo;
○ Timely: Los tests deben seguir estrictamente el criterio de puntualidad.
Además de esto, lo ideal es que sean escritos antes del propio código, pues
evita que sea muy complejo para realizar el test.
El Clean Code es un concepto que llegó y se quedó. Sus principios solucionan con
eficacia uno de los principales problemas que gran parte de los proyectos de
sistemas enfrentan: el mantenimiento de código.
Es muy difícil seguir todas estas reglas cuando se empieza a escribir código. El truco está
en ir mejorando el código en etapas. Escribir, hacer funcionar, refactorizar para dejarlo
mejor (regla del boy scout sobre nuestro propio código).
2. Documentación
Un javadoc es un programa, que toma los comentarios que se colocan en el código con
marcas especiales y construye un archivo HTML con clases, métodos y la documentación
correspondiente. Este HTML tiene el formato de toda la documentación estándar de Java
provista por Sun Microsystems; Javadoc extrae dichos comentarios y genera con ellos un
juego de documentación en formato HTML.
Javadoc es el estándar para documentar clases de Java. La mayoría de los IDEs para Java
utilizan javadoc para generar de forma automática documentación de clases.
Javadoc fue uno de los primeros generadores de documentación en lenguaje Java. Antes
del uso de generadores de documentación, se acostumbraba utilizar redactores técnicos
que normalmente escribían sólo documentación independiente para el software, pero era
mucho más difícil mantener esta documentación sincronizada con el propio software.
Los entornos de programación que implementa Java, como Eclipse o Netbeans, incluyen
esta herramienta. Para que JavaDoc pueda generar las páginas HTML es necesario seguir
una serie de normas de documentación en el código fuente, estas son:
● Los comentarios de Javadoc se generan desde el código fuente y, por lo tanto, hay
que incluir en el mismo etiquetas especiales para poder interpretarlas en la
generación. La etiqueta que determina un comentario Javadoc es /**..*/, es decir,
empiezan por /** y terminan por */.
A continuación se ofrece una tabla con las etiquetas principales que se usan en Javadoc
con su descripción funcional:
Etiqueta Descripción
@throw
Nota:
1. Propósito: "@throws" se utiliza para indicar que el método puede lanzar una
excepción específica, mientras que "@exception" se utiliza para documentar
excepciones generales o no específicas.
2. Sintaxis: "@throws" se utiliza seguido del nombre de la excepción específica
que se puede lanzar, mientras que "@exception" se utiliza para documentar
una excepción general o no específica y no requiere un nombre de excepción
específico.
3. Ubicación: En general, "@throws" se coloca después de la documentación
del método, mientras que "@exception" se coloca antes de la documentación
del método.
Comentarios de clases
/**
* Frase corta descriptiva
* Descripción de la clase
* @author Nombre Apellido / Empresa
* @version 0.1, 2023/02/17
*/
Comentarios de Métodos
Podemos ver cómo se incluyen los comentarios de los métodos en el siguiente ejemplo. En
él vemos la manera de especificar la descripción, los parámetros, el tipo de retorno y las
excepciones que se lanzan. También vemos cómo se referenciaría la llamada a otro
método.
Ejemplo:
/**
* Frase corta descriptiva
* Descripción del método.
* Mención al uso{@link es.loquesea.$app.util.Otra#unMetodo
unMetodo}.
* @param param1 descripción del parámetro.
* @return qué devuelve el método.
* @exception tipo de excepción que lanza el método y en qué
caso
* @see paquete.Clase#metodo Código al que se hace referencia
* @throws IllegalArgumentException el param1 no tiene el
formato deseado
*/
Comentarios de Variables
http://www.oracle.com/technetwork/java/javase/documentation/index-jsp-135444.html
3. Refactorización
¿Qué es la refactorización?
Programar software conlleva un proceso largo que suele involucrar, al menos parcialmente,
a varios desarrolladores, por lo que durante el desarrollo el código fuente a menudo se
amplía y modifica. Si además de estos cambios, tenemos en cuenta que se trabaja a
contrarreloj y utilizan ciertas prácticas anticuadas, observamos como resultado una
acumulación de elementos defectuosos en el código fuente, los llamados code smells.
Estos puntos débiles, que van aumentando a medida que avanza el proceso, ponen en
peligro la funcionalidad y la compatibilidad del software en cuestión. Para evitar esta erosión
continua del programa, se utiliza la refactorización o refactoring.
Este proceso resulta mucho más económico que reescribir la estructura del código desde
cero. La refactorización desempeña un papel especialmente importante en el desarrollo
iterativo e incremental, así como en el desarrollo ágil de software, ya que este modelo
cíclico lleva a los programadores a modificar el software una y otra vez. En este proceso, la
refactorización es un paso clave.
Debemos tener en cuenta que un código puede degenerar a lo largo del tiempo y
convertirse en un llamado código espagueti. Ya sea por falta de tiempo, por falta de
experiencia o por directrices poco claras, las órdenes innecesariamente complejas en la
programación del código acaban obstaculizando su funcionalidad. Cuanto más rápido y
complejo sea el ámbito de aplicación de un código, más se erosionará.
El término código espagueti hace referencia a códigos fuente confusos y de difícil lectura,
cuya estructura es difícil de comprender para los programadores. Algunos ejemplos típicos
de elementos que complican el código son las órdenes de salto (GOTO) redundantes, que
indican al programa que vaya saltando de un sitio a otro en el código; los bucles for/while y
los comandos if.
Concretamente, los proyectos en los que trabajan muchos desarrolladores suelen generar
un código poco legible. Si un código que ya de por sí presentaba ciertas imperfecciones
pasa por muchas manos, es difícil evitar que se encadenen modificaciones a modo de
parche y que, finalmente, se requiera una revisión del código para corregirlo.
En el peor de los casos, el código espagueti puede poner en peligro todo el proceso de
desarrollo del software, llegando a un punto en el que ni siquiera la refactorización puede
resolver el problema. Los llamados code smells y el code rot (es decir, los defectos y la
erosión del software) no tienen por qué ser tan preocupantes si se realiza un refactoring en
cuanto aparezcan los primeros signos de code smells, ya que si no el código seguirá
erosionándose y perderá su funcionalidad a causa del code rot (el proceso de putrefacción,
¿Cuál es el objetivo de la refactorización?
Los métodos aplicados en la refactorización son tan variados como los errores que tratan de
corregir. De manera general, la refactorización del código se guía por sus errores y va
mostrando los pasos necesarios para acortar o eliminar procesos de corrección. Algunas de
las fuentes de error que pueden corregirse mediante refactoring son las siguientes:
La refactorización debe llevarse a cabo antes de modificar una función del programa. En el
mejor de los casos, debe realizarse en muy pocos pasos y comprobando cada modificación
del código mediante procesos de desarrollo de software como el desarrollo guiado por
pruebas (TDD, por sus siglas en inglés) y la integración continua (CI). En pocas palabras, el
TDD y la CI se encargan de poner a prueba los nuevos segmentos de código creados por
los programadores, que luego son integrados y cuya funcionalidad es evaluada mediante
procesos de prueba, a menudo automatizados.
Por regla general, un programa ha de ser modificado en pocos pasos y desde dentro, sin
que su función externa se vea afectada. Tras cada cambio, debe realizarse un test que esté
automatizado en la medida de lo posible.
Nota:
El Desarrollo Guiado por Pruebas (TDD, por sus siglas en inglés "Test Driven
Development") es una técnica de desarrollo de software que consiste en escribir pruebas
automatizadas antes de escribir el código que implementa la funcionalidad.
Este ciclo se repite varias veces durante el proceso de desarrollo, y cada iteración mejora la
calidad del código y la confianza en su comportamiento.
La Integración Continua (CI, por sus siglas en inglés "Continuous Integration") es una
práctica de desarrollo de software que consiste en la integración regular y automática del
código escrito por los miembros de un equipo de desarrollo.
En CI, cada vez que un desarrollador hace cambios en el código, estos cambios se integran
automáticamente con el resto del sistema. Se ejecutan pruebas automatizadas para
asegurar que el código nuevo no rompa el sistema existente y se generan informes de
calidad del código.