32 puntos por xguru 2024-09-02 | 6 comentarios | Compartir por WhatsApp
  • El refactoring de código cumple un papel importante para mantener saludable una base de código
  • Sin embargo, un refactoring mal hecho puede terminar volviendo el código más complejo y más difícil de mantener
  • Hay que saber distinguir entre un buen refactoring y uno malo, y cómo evitar las trampas del mal refactoring

Lo bueno, lo malo y lo feo del refactoring

  • La abstracción puede ser buena o mala. La clave está en saber cuándo y cómo aplicarla
  • Se explican algunas trampas comunes y cómo evitarlas (se omite el código original)

1. Cambiar mucho el estilo de código

  • Los desarrolladores a menudo cometen el error de cambiar por completo el estilo de código durante un refactoring
  • Introducir nuevas librerías o adoptar un estilo de código totalmente distinto puede afectar negativamente la mantenibilidad
  • Es mejor mejorar el código para que sea más idiomático y fácil de leer, sin introducir un paradigma completamente nuevo ni dependencias externas

2. Abstracción innecesaria

  • Es problemático agregar demasiadas abstracciones nuevas sin entender el código existente
  • Eso solo puede aumentar la complejidad y dificultar la comprensión
  • Conviene separar la lógica en funciones pequeñas y reutilizables, pero sin introducir complejidad innecesaria

3. Agregar inconsistencia

  • Actualizar solo una parte de la base de código para que funcione de una forma completamente distinta puede generar confusión y frustración
  • Si se necesita introducir un patrón nuevo, primero es mejor obtener el acuerdo del equipo
  • Es importante mantener un enfoque consistente para la obtención de datos en toda la aplicación

4. No entender el código antes de refactorizar

  • Aprender el código mientras se refactoriza no es una buena idea
  • Puede introducir bugs, degradar el rendimiento y eliminar funcionalidades
  • Antes de refactorizar, es importante entender el código a fondo y mejorarlo manteniendo el comportamiento existente

5. Entender el contexto de negocio

  • Tomar decisiones técnicas sin entender el negocio puede ser desastroso
  • En el caso de un sitio de comercio electrónico que depende mucho del SEO, el renderizado del lado del cliente puede ser una mala elección
  • Un enfoque de renderizado del lado del servidor como Next.js o Remix puede ser una mejor opción en términos de SEO y rendimiento

6. Exceso de consolidación de código

  • No es bueno consolidar código para que quede "limpio" a costa de sacrificar flexibilidad
  • Al abstraer, siempre hay que considerar los casos de uso que se están cubriendo
  • Hay que asegurarse de que la abstracción permita todas las funcionalidades que ofrecía la implementación original

Refactorizar de la manera correcta

  • El refactoring de código es necesario. Pero debe hacerse de la manera correcta
  • Nuestro código no es perfecto y necesita orden, pero hay que mantener la consistencia con la base de código existente
  • Hay que refactorizar después de entender bien el código, y elegir las abstracciones con cuidado
  • Consejos para un refactoring exitoso:
    • Avanzar de forma gradual: hacer cambios pequeños y manejables en lugar de una reescritura total
    • Entender el código a fondo antes de introducir un refactoring importante o una nueva abstracción
    • Mantenerse alineado con el estilo de código existente: la consistencia es clave para el mantenimiento
    • Evitar introducir demasiadas abstracciones nuevas: mantenerlo simple, salvo que la complejidad realmente sea necesaria
    • Evitar agregar nuevas librerías con estilos de programación muy distintos, especialmente sin el acuerdo del equipo
    • Escribir pruebas antes de refactorizar y actualizarlas a medida que se avanza. Esto permite verificar que se conserva la funcionalidad original
    • Asumir responsabilidad compartida entre colegas para que todos respeten estos principios

Herramientas y técnicas para un mejor refactoring

  • Para lograr un mejor refactoring, vale la pena considerar el uso de las siguientes técnicas y herramientas:

Herramientas de linting

  • Usar herramientas de linting para aplicar un estilo de código consistente y detectar problemas potenciales
  • Con Prettier es posible autoformatear con un estilo consistente
  • Con Eslint se pueden realizar verificaciones de consistencia más detalladas mediante plugins personalizados

Revisión de código

  • Implementar revisiones de código exhaustivas para recibir feedback de colegas antes de fusionar el código refactorizado
  • Ayuda a detectar problemas potenciales de forma temprana y a confirmar que el código refactorizado cumpla con los estándares y expectativas del equipo

Testing

  • Escribir y ejecutar pruebas para asegurar que el código refactorizado no rompa la funcionalidad existente
  • Vitest es un test runner especialmente rápido, robusto y fácil de usar, sin necesidad de configuración por defecto
  • Considerar el uso de Storybook para pruebas visuales
  • React Testing Library es un buen conjunto de utilidades para probar componentes de React (también existen variantes para Angular y otros)

Herramientas de AI (adecuadas)

  • Apoyar los esfuerzos de refactoring con herramientas de AI que puedan ajustarse al estilo y las reglas de código existentes
  • Visual Copilot es una herramienta especialmente útil para mantener la consistencia al desarrollar frontend
    • Ayuda a convertir diseños en código manteniéndose alineado con el estilo de código existente y aprovechando correctamente los componentes y tokens del sistema de diseño

Conclusión

  • El refactoring es una parte necesaria del desarrollo de software, pero debe hacerse con cuidado y considerando la base de código existente y la dinámica del equipo
  • El objetivo del refactoring es mejorar la estructura interna del código sin cambiar su comportamiento externo
  • Los mejores refactorings a menudo son invisibles para el usuario final, pero facilitan mucho la vida del desarrollador
  • Mejoran la legibilidad, la mantenibilidad y la eficiencia, sin volver caótico al sistema completo
  • Cuando quieras hacer un "gran plan" para el código, da un paso atrás, entiende el código a fondo, considera el impacto de los cambios y haz mejoras graduales que el equipo pueda apreciar
  • Tu yo del futuro y tus colegas agradecerán un enfoque reflexivo para mantener la base de código limpia y mantenible

6 comentarios

 
toaonly 2024-09-04

Hay quienes se lanzan de golpe a refactorizar incluso sin código de pruebas.
Cuando los veo, siento como si estuvieran haciendo equilibrio sobre una cuerda floja peligrosísima, y hasta da escalofríos jaja

 
ahwjdekf 2024-09-03

El punto 4, "no entender el código antes de refactorizar", realmente me llegó mucho.

 
bichi 2024-09-02

Es algo demasiado obvio, casi como conocimientos básicos jaja. Está bien verlo ordenado así. Creo que cuando refactorizas, el código sale 100% mejor; si no, ¿no significaría que mis habilidades retrocedieron respecto a ayer?

Al ver que puso por escrito algo tan obvio, da la impresión de que alguien dejó todo hecho un desastre y escribió esto de lo verdaderamente molesto que estaba jajaja

 
kandk 2024-09-02

Más que sobre cómo hacer bien el refactoring, trata de cómo programar bien de forma práctica en el trabajo real..
(Parece un texto escrito con frustración porque llegó un junior, dijo que iba a refactorizar un proyecto legacy, complicó todo por todos lados y además metió bugs...)

 
savvykang 2024-09-02

Las personas que no logran distinguir o que confunden la unidad del trabajo con la unidad del código terminan haciendo ese tipo de refactorización, sin importar si tienen mucha o poca experiencia. Al final, un código que sea fácil de corregir y mantener solo cumple su objetivo si, incluso cuando llegue otra persona después, puede entender el flujo del trabajo; y a veces pienso que eso es algo que de verdad no se puede comprender si no se ha vivido en el trabajo real.

 
savvykang 2024-09-02

En React, una vez vi un caso que me pareció una señal de abstracción excesiva: aunque el componente de tabla ya estaba abstraído por el framework de UI, si los esquemas de dos tablas parecen similares, creo que hay que evitar crear un componente nuevo que no cumple ningún rol real solo por usar inversión de control. Al ver casos donde, por querer aplicar Atomic Design, se abusa de componentes vacíos de diez líneas, me resultó muy incómodo porque había que revisar demasiadas partes.

La intención de la regla DRY era no copiar y pegar código exactamente igual y con la misma función, pero parece inevitable que siempre haya gente que la malinterprete. ¿Será en este contexto que surgió eso de no idolatrar los patrones de diseño?