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 funciones, lo que lleva a un código más fácil de usar, limpio y legible.

Cada vez que cambiamos el código sin refactorizarlo, la podredumbre empeora y se propaga. Code rot nos frustra, nos cuesta tiempo y acorta indebidamente la vida útil de los sistemas útiles. En un contexto ágil, puede significar la diferencia entre cumplir o no cumplir con un plazo de iteración.

La refactorización del código evita despiadadamente que se pudra, manteniendo el código fácil de mantener y ampliar. Esta extensibilidad es la razón para refactorizar y es la medida de su éxito. Pero tenga en cuenta que es sólo "safe” para refactorizar el código de manera tan extensa si tenemos extensos conjuntos de pruebas unitarias del tipo que obtenemos si trabajamos primero con la prueba. Sin poder ejecutar esas pruebas después de cada pequeño paso en una refactorización, corremos el riesgo de introducir errores. Si está realizando un verdadero desarrollo basado en pruebas (TDD), en el que el diseño evoluciona continuamente, entonces no tiene opción sobre la refactorización regular, ya que así es como evoluciona el diseño.

Código de higiene

Una metáfora popular para la refactorización es limpiar la cocina mientras cocinas. En cualquier cocina en la que se preparen varias comidas complejas por día para más de un puñado de personas, normalmente encontrará que la limpieza y la reorganización se realizan continuamente. Alguien se encarga de mantener los platos, las ollas, la cocina misma, la comida, el refrigerador todo limpio y organizado de momento a momento. Sin esto, la cocción continua colapsaría pronto. En su propio hogar, puede ver efectos no triviales al posponer incluso pequeñas cantidades de refactorización de platos: ¿alguna vez trató de raspar la suciedad formada por Cocoa Crispies secos de un tazón? Una oportunidad perdida de dos segundos de enjuague puede convertirse en diez minutos de raspado agresivo.

“Refactorizaciones” específicas

Las refactorizaciones son lo opuesto a juguetear interminablemente con el código; son precisos y finitos. La definitiva de Martin Fowler primer libro sobre el tema describe 72 "refactorizaciones" específicas por nombre (por ejemplo, "método de extracción", que extrae un bloque de código de un método y crea un nuevo método para él). Cada refactorización convierte una sección de código (un bloque, un método, una clase) de uno de los 22 estados "olorosos" bien entendidos a un estado más óptimo. Se necesita un tiempo para aprender a reconocer las oportunidades de refactorización y para implementar las refactorizaciones correctamente.

Refactorización a patrones

La refactorización no solo ocurre en niveles bajos de código. En su reciente libro, Refactorización de patrones, Joshua Kerievsky argumenta hábilmente que la refactorización es la técnica que debemos usar para introducir patrones de diseño de "pandilla de cuatro" en nuestro código. Argumenta que los patrones a menudo se usan en exceso y, a menudo, se introducen demasiado pronto en los sistemas. Sigue el formato original de Fowler de mostrar y nombrar "refactorizaciones" específicas, recetas para llevar su código del punto A al punto B. Las refactorizaciones de Kerievsky son generalmente de mayor nivel que las de Fowler y, a menudo, usan las refactorizaciones de Fowler como bloques de construcción. Kerievsky también introduce el concepto de refactorización "hacia" un patrón, describiendo cuántos patrones de diseño tienen varias implementaciones diferentes o profundidades de implementación. A veces necesita más de un patrón que en otras ocasiones, y este libro le muestra exactamente cómo conseguir una parte del camino hasta allí, o todo el camino hasta allí.

El flujo de la refactorización

En un contexto de prueba primero, la refactorización tiene el mismo flujo que cualquier otro cambio de código. Tienes tus pruebas automatizadas. Comienza la refactorización haciendo el cambio discreto más pequeño que pueda compilar, ejecutar y funcionar. Siempre que sea posible, realice dichos cambios agregándolos al código existente, en paralelo con él. Ejecutas las pruebas. A continuación, realiza el siguiente pequeño cambio discreto y vuelve a ejecutar las pruebas. Cuando la refactorización está en su lugar y todas las pruebas se ejecutan sin problemas, regresa y elimina el viejo código paralelo maloliente. Una vez que las pruebas se ejecutan limpias después de eso, habrá terminado.

Automatización de refactorización en IDE

La refactorización es mucho, mucho más fácil de hacer automáticamente que a mano. Afortunadamente, cada vez más entornos de desarrollo integrados (IDE) están incorporando soporte de refactorización automatizado. 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 de .NET, hay al menos dos complementos de herramientas de refactorización para Visual Studio 2003, y se nos dice que las versiones futuras de Visual Studio tendrán soporte de refactorización incorporado.

Para refactorizar código en Eclipse o IDEA, seleccione el código que desea refactorizar, despliegue la refactorización específica que necesita de un menú y el IDE hace el resto del trabajo duro. Los cuadros de diálogo le solicitan apropiadamente nuevos nombres para las cosas que necesitan nombres y para entradas similares. Luego puede volver a ejecutar sus pruebas de inmediato para asegurarse de que el cambio no haya roto nada. Si algo se rompió, puede deshacer fácilmente la refactorización e investigar.