Appearance
Criterios de Abstracción de Código
Concepto
La abstracción de código duplicado es una técnica fundamental de refactoring, pero no todo código duplicado debe ser abstraído. Existe un balance entre eliminar duplicación y evitar sobre-ingeniería que complique innecesariamente el sistema.
Principio Fundamental
"Pragmatism over Perfect Abstraction"
El objetivo no es eliminar toda duplicación, sino mantener un código que sea:
- Fácil de entender
- Fácil de modificar
- Fácil de mantener
Rule of Three
Concepto
La "Regla de Tres" establece un umbral pragmático:
- Primera ocurrencia: Implementar directamente
- Segunda ocurrencia: Notar la duplicación, pero esperar
- Tercera ocurrencia: Considerar abstracción
Este enfoque evita abstracciones prematuras basadas en patrones que aún no están consolidados.
Excepciones
La regla se aplica con criterio, considerando:
- Complejidad del código duplicado
- Frecuencia de cambios esperada
- Contexto de uso
Criterios para NO Abstraer
1. Código Trivial
Definición: Código extremadamente simple (< 5-10 líneas)
Justificación:
- El overhead de comprensión de la abstracción supera el beneficio
- La duplicación es obvia y fácil de mantener
- Cambios son poco probables
Ejemplo conceptual: Métodos que simplemente retornan un valor por defecto si un parámetro es nulo.
2. Contextos Diferentes
Definición: Código similar usado en contextos con propósitos distintos
Justificación:
- Aunque el código se vea similar, representa conceptos diferentes
- Evolución futura puede divergir
- La cohesión se pierde al forzar la abstracción
Ejemplo conceptual: Validaciones que comparten estructura pero validan reglas de negocio diferentes en distintos módulos.
3. Frecuencia de Cambios
Definición: Código estable que no cambia frecuentemente
Justificación:
- Si el código no cambia, la duplicación no genera deuda técnica
- La abstracción no aporta beneficio de mantenimiento
- El costo de comprensión no se amortiza
4. Overhead Cognitivo
Definición: La abstracción requiere más esfuerzo mental que la duplicación
Justificación:
- Desarrolladores deben navegar a otra ubicación para entender
- Aumenta indirección sin beneficio proporcional
- Reduce la localidad del código
Criterios para SÍ Abstraer
1. Código Complejo
Umbral: > 20-30 líneas de lógica no trivial
Beneficio:
- Cambios centralizados
- Reducción de superficie de error
- Facilita testing aislado
2. Alta Frecuencia de Duplicación
Umbral: 5+ ocurrencias
Beneficio:
- Impacto significativo en reducción de código
- Mayor probabilidad de evolución conjunta
- Patrones consolidados
3. Responsabilidad Única Clara
Indicador: La lógica duplicada tiene un propósito único bien definido
Beneficio:
- Cohesión alta en la abstracción
- Interfaz clara y estable
- Reutilización sin acoplamiento
4. Evolución Conjunta
Indicador: Cuando el código cambia, todos los duplicados deben cambiar igual
Beneficio:
- Un cambio actualiza todas las ocurrencias
- Previene inconsistencias
- Reduce esfuerzo de mantenimiento
Estrategias de Abstracción
Traits (Comportamiento Compartido)
Cuándo usar:
- Comportamiento común entre clases sin relación jerárquica
- Métodos auxiliares reutilizables
- Cross-cutting concerns
Ejemplo conceptual: Funcionalidad de auditoría compartida por múltiples servicios sin relación de herencia.
Clases de Utilidad
Cuándo usar:
- Funciones puras sin estado
- Transformaciones de datos comunes
- Operaciones matemáticas o string
Servicios Dedicados
Cuándo usar:
- Lógica de negocio compleja compartida
- Requiere dependencias propias
- Justifica ser un componente independiente
Análisis de Trade-offs
Costo de Duplicación vs. Costo de Abstracción
Duplicación:
- ✅ Localidad del código
- ✅ Simplicidad de comprensión
- ❌ Múltiples puntos de cambio
- ❌ Posibles inconsistencias
Abstracción:
- ✅ Cambio centralizado
- ✅ Reducción de código
- ❌ Indirección
- ❌ Complejidad conceptual
Métricas de Decisión
Duplicación aceptable cuando:
(Frecuencia × Complejidad × Tasa_de_cambio) < Umbral_de_abstracciónAbstracción justificada cuando:
(Frecuencia × Complejidad × Tasa_de_cambio) > Umbral_de_abstracciónPatrón WET vs DRY
DRY (Don't Repeat Yourself)
Principio tradicional: eliminar duplicación
Aplicación pragmática:
- Válido para código complejo y frecuente
- No aplicar dogmáticamente
WET (Write Everything Twice/Thrice)
Enfoque pragmático: tolerar duplicación limitada
Justificación:
- Código optimizado para lectura, no para escritura
- Previene abstracciones prematuras
- Permite que patrones emerjan naturalmente
Checklist de Decisión
Antes de abstraer código duplicado:
- [ ] ¿Se cumple la Rule of Three? (3+ ocurrencias)
- [ ] ¿Es código complejo? (> 20 líneas)
- [ ] ¿Cambia frecuentemente?
- [ ] ¿Tiene responsabilidad única clara?
- [ ] ¿Evolucionará de forma conjunta?
- [ ] ¿La abstracción simplifica vs. complica?
- [ ] ¿El beneficio supera el costo cognitivo?
Si la mayoría es NO → No abstraer Si la mayoría es SÍ → Considerar abstracción
Refactoring Incremental
Estrategia
- Tolerar duplicación inicial hasta que el patrón sea claro
- Observar evolución del código duplicado
- Abstraer cuando criterios se cumplan orgánicamente
- Documentar decisión de NO abstraer cuando sea apropiado
Anti-patrones
Over-Engineering: Crear jerarquías complejas para eliminar 3 líneas duplicadas
Premature Abstraction: Abstraer antes de que el patrón esté consolidado
Forced Generalization: Forzar casos diferentes en una abstracción genérica que no encaja
Documentación de Decisiones
Cuando se decide NO abstraer, documentar:
- Razón de la decisión
- Criterios evaluados
- Umbral para reconsiderar en el futuro
Esto previene refactorings innecesarios futuros y comunica intención arquitectónica.
Nivel de Aplicación: Arquitectura General Tipo: Guía de Diseño Complejidad: Media-Alta Impacto: Alto en mantenibilidad a largo plazo