\subsection{Refactoring y Test Driven Development}
\label{sec:RTDT}

Como ya se ha comentado en el apartado anterior, el uso de nuestro software se enmarca en el contexto de un desarrollo dirigido por tests.
Por ello es necesario hacer una explicación mas profunda tanto del {\it Test Driven Development} como del {\it Refactoring}.

Según Fowler, el Refactoring es el proceso de cambiar un sistema de software de tal manera que no altere el comportamiento exterior del código y mejore su estructura interna.
Esta práctica es un método sencillo y disciplinado que ayuda a optimizar el software teniendo en cuenta diferentes factores.

La mejora del diseño es el factor principal, por encima de otros factores como la optimización.
Sin refactorización, cuanto más amplio sea el código, más complicada será la estructura y el diseño carecerá de inteligibilidad.
En cambio, si, desde el inicio del desarrollo, refactorizamos cada vez que creamos una nueva función o ampliamos una creada con anterioridad, el crecimiento del código no será equivalente al aumento de complejidad de su estructura, con lo cual, se facilita tanto el mantenimiento como la evolución del software.

Una de las premisas del Extreme Programming es el trabajo en equipo.
Los grupos de trabajo son pequeños y el contacto durante el desarrollo es físico ({\it pair programming}).
La interrelación en el grupo causa que todo el equipo sea responsable de todo el código.
Por lo tanto, es básico para un desarrollo satisfactorio del sistema que el código pueda ser inteligible por todos los componentes del proyecto.
Si refactorizamos habitualmente, el código estará siempre depurado, será inteligible por todos los desarrolladores y el esfuerzo que realizaremos para las modificaciones pertinentes será mínimo.

La problemática de un código sin refinar es evidente a la hora de buscar bugs.
Si el software no sigue una estructura simple que facilite su comprensión, en el momento que hay un fallo inesperado para un caso concreto, la búsqueda de dicho fallo implica un coste muy alto.
Con el Refactoring, se simplifica la búsqueda de bugs y permite tener un software más robusto.

Aunque al principio pueda costar acostumbrarse a seguir la disciplina del Refactoring, una vez habituados, se agiliza el desarrollo.
Esta agilización se debe a que el proceso se realiza a partir de pequeños pasos que evitan al desarrollador encontrarse en procesos altamente complejos y facilita la revisión de métodos ya realizados.

El {\it Refactoring} permite obtener un código depurado, robusto y comprensible.
Sin embargo, otra premisa del {\it Refactoring} es no modificar la funcionalidad aunque se modifique el código.
Para comprobrar que el sistema sigue funcionando correctamente independientemente de los cambios, se usa el {\it Test Driven Developement}.
Un test unitario comprueba el correcto funcionamiento de una unidad funcional concreta, la cual puede estar desarrollada en uno o varios métodos.
El proceso del {\it Test Driven Developement} está formado por 3 fases que se repiten iterativamente: Red-Green-Refactor.

\paragraph{Red}

Durante esta fase se fija el siguiente objetivo funcional a abarcar mediante un test.
Se modifica el código lo mínimo para que compile, ejecute y falle el test.
Los test fallados se indican en rojo, de ahí el nombre de la fase.
Haciendo que falle el test, comprobamos que el test detecta la falta de esa funcionalidad.


\paragraph{Green}

El objetivo de esta fase es cubrir la funcionalidad fijada anteriormente.
Para ello, se implementa el mínimo código posible para pasar el test,
el cual se indicará en verde.
De esta manera, no implementaremos más código del necesario para pasar el test
y nos aseguramos que todo el código esté cubierto por un test.


\paragraph{Refactoring}
El objetivo del refactoring es reducir la entropía del código.
Para ello modificaremos el código iterativamente,
después de cada modificación en el código, testeamos y, si pasan todos, podemos seguir refactorizando.
De esta forma, podemos llegar a la implementación que normalmente haríamos de forma directa con pasos controlados y bajo la seguridad de los tests
