¿Leer 50 líneas de código o utilizar la refactorización de métodos extraídos? - Ideas de Derek Comartin
En el mundo del desarrollo de software, la refactorización es esencial. Una de las técnicas más comunes y recomendadas es la refactorización de métodos de extracción, que consiste en dividir un fragmento grande de código en métodos más pequeños y reutilizables para mejorar la legibilidad y la reutilización. Aunque en teoría suena ideal, Derek Comartin, en su vídeo "Prefiero leer 50 líneas que Extract Method Refactoring", ofrece una visión fresca y crítica.
Este artículo te llevará a través del desglose de Derek de la refactorización de métodos de extracción, ofreciendo un contexto del mundo real y consejos prácticos. Seguiremos su razonamiento exacto y la estructura del código a medida que nos guía a través de cuándo y cómo aplicar la refactorización de extracción, junto con sus detalles de implementación y posibles desventajas.
El Ejemplo: Registro de usuarios en un sistema de chat
Al principio del vídeo, Derek presenta un ejemplo: una función de registro para un sistema de chat. Se trata de un bloque de código compacto pero realista de unas 50 líneas que realiza varias tareas:
-
Comprueba si el nombre de usuario no está en blanco
-
Comprueba si el nombre de usuario ya está ocupado
-
Gestión de canales con restricciones de edad
-
Guarda el nuevo objeto de usuario
- Envía un correo electrónico con un enlace de activación
Este código reside en una función y, a primera vista, podría parecer un buen candidato para la refactorización de métodos de extracción. Pero, como advierte Derek, refactorizar a ciegas sin entender el impacto puede degradar la claridad.
Comenzando con la refactorización: Seleccionar método de extracción
Derek empieza como muchos desarrolladores: dividiendo el fragmento de código en partes más pequeñas. Muestra cómo seleccionar Extract Method a través del menú contextual o de un atajo de teclado en la mayoría de los IDE o editores de código.
Extrae:
-
validateUsername para verificar que el nombre de usuario no está en blanco
-
existingSignUpNotActivated para comprobar si hay una cuenta sin activar
-
validateExistingUser para gestionar todas las comprobaciones de usuarios existentes
-
filterAgeRestrictedChannels para procesar canales de usuarios menores de 18 años
- sendEmail para enviar el mensaje de bienvenida
Da a cada nueva función un nombre significativo, que es uno de los principales consejos que se promueven a menudo en las prácticas de código limpio. Pero a medida que avanza por estas versiones modificadas, Derek comienza a señalar las grietas en la lógica, no en la funcionalidad, sino en la legibilidad y el flujo de control.
Tema 1: Detalles de implementación ocultos
Una de las primeras señales de alarma que destaca Derek es que los detalles de implementación ahora se ocultan detrás de métodos extraídos.
Por ejemplo, los métodos validateUsername y validateExistingUser en realidad lanzan excepciones. Pero como desarrollador que lee el código refactorizado, no tendría ni idea a menos que acceda a su interior.
Este tipo de refactorización puede ocultar la lógica de control y dar lugar a errores o validaciones omitidas. El alcance y el flujo ya no son obvios. En lugar de hacer el código más claro, se está creando un laberinto de abstracciones donde los efectos secundarios como excepciones o variables modificadas ya no son visibles en el formulario donde se escribió originalmente la lógica.
Número 2: Indirección y extractos encadenados
A continuación, Derek señala el problema de la indirección: cuando un método de extracción llama a otro, etcétera. Muestra cómo el método validateExistingUser se compone a su vez de existingSignUpNotActivated.
Ya no se trata de leer un bloque de código directo de arriba abajo. Estás saltando entre métodos, archivos y clases sólo para rastrear lo que sucede. Y aunque el editor puede ayudar a navegar por este flujo, se convierte en una carga para la carga cognitiva del lector.
Esto resulta aún más difícil en sistemas más grandes en los que la refactorización abarca varios archivos o componentes. De repente, tu "código limpio" parece más difícil de seguir que las 50 líneas "desordenadas" originales.
Tema 3: Variables locales y estado mutante
Una de las lecciones más importantes de este vídeo proviene del manejo de las variables locales y la mutación de estados.
Derek destaca el método filterAgeRestrictedChannels. No devuelve un resultado, sino que muta directamente la lista de canales que se le ha pasado. Esto significa que está modificando el estado local desde dentro de un método diferente, y a menos que inspeccione el método de cerca, este cambio está oculto.
Esto rompe con la expectativa de que una función es una operación pura o señala claramente cuándo está cambiando cosas. Cuando se sustituye la lógica por un nuevo método que no devuelve valores, sino que los modifica internamente, se están introduciendo riesgos y confusión.
Alternativa refactorizada de Derek
¿Cómo refactoriza Derek su antiguo código?
Propone un enfoque mucho más sencillo:
-
Mantenga la lógica autoexplicativa en línea. La comprobación inicial de un nombre de usuario vacío se mantiene en el método principal, ya que es fácil de entender y no desordena la base de código.
-
Devolver resultados en lugar de mutar. En lugar de mutar la lista de canales, la función filterAgeAppropriateChannels devuelve ahora una lista filtrada. Esto aclara el flujo de datos y evita efectos secundarios inesperados.
-
Utilice métodos de extracción sencillos y predecibles. El único otro método extraído es isExistingUserAlreadyActivated, que devuelve claramente un booleano sin lanzar excepciones. Encapsula la lógica sin ocultar detalles.
- Evite efectos secundarios en línea como el envío de correos electrónicos. Derek deja la lógica del correo electrónico en su lugar para la demostración, pero sugiere que en un sistema real, esto debe ser manejado a través de un evento en un proceso separado o hilo, no algo ligado directamente a la presentación del formulario de usuario.
En total, Derek sólo utiliza dos métodos de extracción y deja el resto de la lógica inline, porque es más fácil de leer, razonar y controlar.
Consejos finales sobre la refactorización de métodos extraídos
El vídeo de Derek nos deja algunas pautas prácticas para utilizar la refactorización de métodos de extracción de forma eficaz:
-
Utilice nombres significativos que describan exactamente lo que hace el método.
-
Evita efectos secundarios como la mutación de estados o el lanzamiento de excepciones a menos que sean obvios.
-
Devolver valores en lugar de modificar los parámetros de entrada.
-
No ocultes la lógica tras múltiples capas de abstracción.
- Si un método parece legible en su forma original, no lo fuerce a convertirse en varias funciones sólo por el bien de la refactorización.
A veces, la mejor abstracción es la ausencia de abstracción, sobre todo si se hace a costa de la claridad y de no perder de vista el ámbito de aplicación.
Conclusión
El enfoque de Derek Comartin cuestiona la idea de que la refactorización siempre mejora el código. En el caso de la refactorización de métodos de extracción, a menudo menos es más. En lugar de utilizar en exceso el Método de Extracción para trocear tu lógica, evalúa qué añade valor, qué facilita la comprensión de tu código y qué oculta detalles importantes.
Con ejemplos claros y una visión directa del código del mundo real, Derek muestra en su vídeo que a veces 50 líneas en un único método, leído de arriba abajo como una historia, son mejores que diez métodos más pequeños repartidos por tu código base.
Si alguna vez has recurrido a ese atajo de teclado para crear un nuevo método, recuerda el consejo de Derek: haz una pausa, evalúa y asegúrate de que la refactorización sirve al lector, no solo al IDE.
