Código de refactorización

La refactorización de código es un esfuerzo directo para mejorar el código sin crear nuevos módulos o funcionalidades, lo que da como resultado un código más fácil de usar, limpio y legible.

Cada vez que modificamos el código sin refactorizarlo, el deterioro se agrava y se extiende. El deterioro del código nos frustra, nos hace perder tiempo y acorta innecesariamente la vida útil de los sistemas. En un contexto ágil, puede significar la diferencia entre cumplir o no con el plazo de una iteración.

La refactorización del código previene de forma implacable la degradación del código, facilitando su mantenimiento y extensión. Esta extensibilidad es la razón de ser de la refactorización y la medida de su éxito. Pero cabe señalar que es solo “safeRefactorizar el código de forma tan exhaustiva solo requiere amplios conjuntos de pruebas unitarias, como los que se obtienen al trabajar con desarrollo guiado por pruebas (TDD). Sin poder ejecutar estas pruebas tras cada pequeño paso de la refactorización, corremos el riesgo de introducir errores. Si se practica un desarrollo guiado por pruebas (TDD) real, donde el diseño evoluciona continuamente, la refactorización regular es imprescindible, ya que es la base de dicha evolución.

Higiene del código

Una metáfora popular para la reorganización es limpiar la cocina mientras se cocina. En cualquier cocina donde se preparen varias comidas elaboradas al día para más de cinco personas, la limpieza y la reorganización son constantes. Alguien se encarga de mantener limpios y organizados los platos, las ollas, la cocina, la comida y el refrigerador en todo momento. Sin esto, cocinar de forma continua sería un desastre. En casa, se pueden observar consecuencias importantes al posponer incluso pequeñas tareas de reorganización: ¿alguna vez has intentado raspar la suciedad que dejan los cereales secos en un tazón? Un enjuague de dos segundos puede convertirse en diez minutos de raspado intenso.

“Refactorizaciones” específicas

Las refactorizaciones son lo opuesto a trastear sin cesar con el código; son precisas y finitas. La definición de Martin Fowler Se publica el libro en inglés El libro describe 72 refactorizaciones específicas (por ejemplo, «extraer método», que extrae un bloque de código de un método y crea uno nuevo). Cada refactorización transforma una sección de código (un bloque, un método, una clase) de uno de los 22 estados «ineficientes» bien conocidos a un estado más óptimo. Aprender a reconocer las oportunidades de refactorización e implementarlas correctamente lleva tiempo.

Refactorización a patrones

La refactorización no solo se produce en los niveles más bajos del código. En su libro reciente, Refactorización a patronesJoshua Kerievsky argumenta convincentemente que la refactorización es la técnica idónea para introducir patrones de diseño de la "banda de los cuatro" en nuestro código. Sostiene que los patrones se utilizan con frecuencia en exceso y se introducen demasiado pronto en los sistemas. Sigue el formato original de Fowler, que consiste en mostrar y nombrar "refactorizaciones" específicas, recetas para llevar el código del punto A al punto B. Las refactorizaciones de Kerievsky suelen ser de un nivel más alto que las de Fowler y, a menudo, utilizan las de Fowler como base. Kerievsky también introduce el concepto de refactorización "hacia" un patrón, describiendo cómo muchos patrones de diseño tienen diversas implementaciones o niveles de profundidad. A veces se necesita un patrón con mayor profundidad que en otras ocasiones, y este libro muestra exactamente cómo lograrlo, ya sea parcialmente o completamente.

El flujo de la refactorización

En un contexto de desarrollo guiado por pruebas (TDD), la refactorización sigue el mismo flujo que cualquier otro cambio de código. Se cuentan con pruebas automatizadas. Se comienza la refactorización realizando el cambio más pequeño y discreto posible que compile, se ejecute y funcione correctamente. Siempre que sea posible, estos cambios se realizan añadiendo código al código existente, en paralelo. Se ejecutan las pruebas. A continuación, se realiza el siguiente cambio pequeño y discreto, y se vuelven a ejecutar las pruebas. Una vez implementada la refactorización y tras ejecutarse correctamente todas las pruebas, se elimina el código paralelo antiguo y redundante. Una vez que las pruebas se ejecutan correctamente, el proceso ha finalizado.

Automatización de la refactorización en los IDE

La refactorización es mucho más fácil de realizar automáticamente que manualmente. Afortunadamente, cada vez más entornos de desarrollo integrados (IDE) incorporan soporte para la refactorización automatizada. Por ejemplo, un IDE popular para Java es eclipse, que incluye más refactorizaciones automáticas todo el tiempo. Otro favorito es IntelliJ IDEA, que históricamente ha incluido aún más refactorizaciones. En el mundo .NET, existen al menos dos complementos de herramientas de refactorización para Visual Studio 2003, y se nos ha informado que las futuras versiones de Visual Studio contarán con soporte integrado para la refactorización.

Para refactorizar código en Eclipse o IntelliJ IDEA, selecciona el código que deseas refactorizar, despliega la opción de refactorización específica que necesitas desde un menú y el IDE se encarga del resto. Aparecerán cuadros de diálogo para que introduzcas los nombres de los elementos que lo requieran y para solicitar información similar. A continuación, puedes volver a ejecutar las pruebas inmediatamente para asegurarte de que el cambio no haya causado ningún problema. Si algo falla, puedes deshacer fácilmente la refactorización e investigar el problema.