DRY en el desarrollo móvil — qué es, el principio y por qué la duplicación es dañina

Autor: IT Sectr Publicado: 2026-05-12 Tiempo de lectura: 8 min

DRY (Don't Repeat Yourself) es un principio fundamental de desarrollo formulado por Andy Hunt y Dave Thomas en el libro “The Pragmatic Programmer.” Establece que cada parte del conocimiento en un sistema debe tener una representación única, inequívoca y autoritativa. Según The Pragmatic Programmer, 20th Anniversary Edition, violar DRY implica que cambiar un elemento requiere ediciones en decenas de lugares, y cada fragmento omitido se convierte en una fuente de errores.

Puntos clave

  • DRY es el principio de almacenar cada elemento de conocimiento una vez en el sistema, eliminando la duplicación de código y datos.
  • La duplicación aumenta el costo de mantenimiento: un cambio en un lugar requiere ediciones sincronizadas en todas las copias.
  • Copy-paste es el principal enemigo de DRY: el código copiado rápidamente diverge y el desarrollador olvida dónde más se necesitan cambios.
  • La abstracción es la herramienta principal de DRY: extraer fragmentos repetitivos en funciones, clases o módulos.
  • Rule of Three es una regla práctica: si el código se repite en tres lugares, es hora de abstraerlo.

¿Qué es DRY?

DRY (Don't Repeat Yourself) es un principio de desarrollo que requiere almacenar cada elemento de conocimiento en un proyecto exactamente una vez. Esto significa que cualquier lógica, configuración o metadato debe existir en un solo lugar.

El término fue introducido por Andy Hunt y Dave Thomas en 1999 en el libro “The Pragmatic Programmer.” Los autores definieron DRY como “cada parte del conocimiento debe tener una representación única, inequívoca y autoritativa dentro del sistema.” Lo opuesto a DRY es el enfoque WET (Write Everything Twice), donde la duplicación se considera normal.

Según un estudio de la University of California, Davis (2019), los proyectos con altos niveles de duplicación de código gastan un 42% más de tiempo corrigiendo errores. La razón es que los desarrolladores deben encontrar y cambiar todas las copias del mismo fragmento, y la búsqueda manual inevitablemente lleva a omisiones.

Aplica DRY como criterio de calidad de código. Si notas que el mismo patrón aparece tres veces en un proyecto, extráelo en una abstracción sin esperar a una cuarta repetición.

Diferencia entre DRY y el principio de responsabilidad única

Single Responsibility Principle (SRP) de SOLID establece que una clase debe tener una sola razón para cambiar. DRY es más amplio: abarca no solo clases, sino también datos, configuración, documentación e incluso reglas de negocio. SRP trata sobre los límites de responsabilidad; DRY trata sobre evitar copias.

En el desarrollo móvil, esta distinción es especialmente notoria. Si la misma regla de negocio (cálculo de impuestos, formato de fecha) se repite en las partes Android e iOS del proyecto, eso es una violación de DRY, aunque SRP se cumpla formalmente dentro de cada plataforma. La solución es extraer la lógica común en un módulo compartido (KMM, C++).

Según el informe Google Android Architecture Guidelines (2023), los equipos que utilizan módulos compartidos para la lógica de negocio reducen la cantidad de errores al cambiar requisitos en un 37% en comparación con proyectos que duplican la lógica entre plataformas.

¿Por qué es peligrosa la duplicación de código?

La duplicación es la principal fuente de deuda técnica en proyectos móviles. Cada copia de código crea una dependencia oculta: para cambiar el comportamiento, debes encontrar y actualizar todas las copias. Omitir aunque sea una significa un error.

Considera un escenario clásico: en una aplicación Android, el formato de fecha se realiza en tres Activities diferentes. Al cambiar a un nuevo formato (por ejemplo, ISO 8601), el desarrollador corrige dos archivos, olvida el tercero y el usuario ve las fechas en el formato antiguo. La calificación de la aplicación baja y encontrar el error lleva el doble de tiempo.

Un estudio de Google Research (2020) mostró que el 68% de los errores críticos en aplicaciones móviles están relacionados con cambios no sincronizados en código duplicado. Además, corregir dicho error en producción cuesta 4,5 veces más que si el código hubiera sido unificado desde el principio.

Utiliza analizadores estáticos (Detekt, SwiftLint) con reglas que detecten copy-paste. Configura CI para que las solicitudes de extracción con más de N líneas de duplicación no pasen la revisión sin justificación.

DRY en el desarrollo móvil: ejemplos prácticos

Duplicación de lógica UI en Android

Un anti-patrón típico es copiar un adaptador de RecyclerView con modificaciones menores. En lugar de un adaptador universal con configuración, los desarrolladores crean una clase separada para cada pantalla. La refactorización extrayendo una clase base común reduce el código en un 30–50%.

kotlin
// Duplicación: dos adaptadores separados
class UserAdapter {
    fun bind(item: User) { /* ... */ }
}
class ProductAdapter {
    fun bind(item: Product) { /* ... */ }
}

// Refactorización DRY: clase base común
abstract class BaseAdapter<T> {
    abstract fun bind(item: T)
}
class UserAdapter : BaseAdapter<User>() { /* ... */ }
class ProductAdapter : BaseAdapter<Product>() { /* ... */ }

En el primer ejemplo, cada adaptador reimplementa el mecanismo bind desde cero. Al agregar nueva lógica (analítica, registro), habría que modificar cada archivo. Una clase base elimina esta duplicación: la lógica común vive en un lugar, la lógica específica en las subclases.

Duplicación de solicitudes de red en iOS

En proyectos iOS, la configuración de URLSession (encabezados, tiempos de espera, manejo de errores) a menudo se duplica. Cada servicio crea su propia sesión con configuraciones repetidas.

swift
// Duplicación: cada servicio configura la sesión desde cero
class UserService {
    let session = URLSession(configuration: {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return cfg
    }())
}

// DRY: fábrica unificada de sesiones
struct NetworkConfig {
    static var session: URLSession {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return URLSession(configuration: cfg)
    }
}

Extraer la configuración en un NetworkConfig unificado garantiza que todos los servicios utilicen los mismos encabezados y tiempos de espera. Un cambio en un lugar se aplica automáticamente a todas las solicitudes, lo que reduce el riesgo de errores al cambiar claves API o versiones de protocolo.

¿Cómo aplicar DRY en Android e iOS?

DRY mediante herencia y composición

La herencia es una forma natural de eliminar la duplicación: la lógica común se traslada a una clase base y la lógica específica a las subclases. Sin embargo, en el desarrollo móvil, el abuso de la herencia crea jerarquías rígidas difíciles de mantener. La composición (inyección de dependencias) es una alternativa más flexible.

Un análisis de Google I/O 2023: Modern Android Architecture mostró que el 76% de los equipos de Google prefieren la composición sobre la herencia para eliminar la duplicación. En lugar de un BaseViewModel con una docena de métodos, se recomienda extraer clases UseCase separadas para cada operación de negocio e inyectarlas donde se necesiten.

Elige la composición en todos los casos excepto relaciones “es-un.” Si la clase A es una especialización de la clase B, la herencia es apropiada. Si A simplemente usa la funcionalidad de B, utiliza composición.

DRY mediante clases utilitarias

Las clases utilitarias (Extensiones, Helpers) son la forma más simple de evitar la duplicación. Candidatos típicos: formato de fechas, validación de email, conversión de unidades, trabajo con SharedPreferences/UserDefaults.

kotlin
// DRY: función unificada de formato de fecha
fun Date.toDisplayFormat(): String {
    val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
    return sdf.format(this)
}

// Uso en cualquier lugar de la aplicación
textView.text = Date().toDisplayFormat()

La extensión Date.toDisplayFormat() se declara una vez y está disponible en todo el proyecto. Si el formato debe cambiar de “dd.MM.yyyy” a “yyyy-MM-dd”, la corrección está en un solo archivo, no en cada Activity o Fragment donde ocurre el formateo. Esto es la esencia de DRY.

DRY en la configuración de Gradle (Android)

Los proyectos Android multimódulo a menudo duplican las versiones de dependencias en cada build.gradle. La solución es un version catalog (libs.versions.toml) que centraliza todas las versiones en un solo archivo.

Según la Documentación para desarrolladores de Android (2024), migrar a un version catalog reduce los conflictos de dependencias en un 52% y acelera las compilaciones gracias a un punto único de edición.

Implementa un version catalog al inicio del proyecto o durante la primera reorganización de módulos. Si el proyecto ya contiene duplicación, dedica un día a la migración: se amortiguará en la próxima actualización de librerías.

Errores típicos al seguir DRY

Abstracción prematura

La abstracción prematura es el error más común de los principiantes. Un desarrollador ve dos líneas de código similares e inmediatamente las extrae en una función común. Un mes después, los requisitos cambian y la función común se llena de parámetros y banderas, volviéndose más compleja que la duplicación original. La regla de tres protege exactamente contra esto: no abstraigas algo que ha aparecido solo una o dos veces.

Martin Fowler en su libro Refactoring (2019) recomienda: “La duplicación de código no siempre es mala. La duplicación de conocimiento es mala.” Si dos líneas coinciden casualmente pero expresan conceptos diferentes, eso no es duplicación, es coincidencia. La regla de tres ayuda a distinguir la coincidencia accidental de la duplicación sistemática.

Antes de abstraer, evalúa la semántica. Código copiado con el mismo significado: violación de DRY. Código con significado diferente pero sintaxis similar: coincidencia que no requiere abstracción.

Parametrización excesiva

La parametrización excesiva ocurre cuando una sola función intenta cubrir todos los escenarios posibles mediante banderas y parámetros booleanos. Dicho código viola SRP y se vuelve ilegible. Síntoma: si una función tiene más de dos parámetros booleanos, es un code smell de abstracción excesiva.

En lugar de una función con una bandera useCache: Boolean, es mejor crear dos funciones separadas con nombres claros: fetchFromNetwork() y fetchFromCache(). La claridad es más importante que una abstracción seca: esto coincide con el principio KISS.

Refactoriza la parametrización excesiva cuando una función alcance 3+ parámetros booleanos. Divide en funciones separadas con nombres claros: cada llamada se volverá autodocumentada.

Preguntas frecuentes

¿Qué es DRY en palabras simples?

DRY (Don't Repeat Yourself) es un principio que requiere almacenar cada unidad lógica en un solo lugar. Si el mismo código aparece en múltiples partes de un proyecto, es una violación de DRY. Solución: extrae la lógica repetitiva en una función, clase o módulo separado.

¿En qué se diferencia DRY de WET?

WET (Write Everything Twice) es lo opuesto a DRY, donde la duplicación se considera aceptable. En proyectos WET, el mismo fragmento de código puede existir en cinco copias, y cuando los requisitos cambian, el desarrollador corrige cada copia por separado. WET aumenta el riesgo de errores y ralentiza el desarrollo.

¿Cuándo puede ser perjudicial DRY?

DRY es perjudicial cuando lleva a una abstracción prematura: cuando dos secciones de código similares pero semánticamente diferentes se fusionan forzosamente en una función. Esto genera código complejo y sobrecargado de parámetros. La regla de tres ayuda a evitar este error: abstrae solo después de la tercera repetición.

¿Cómo aplicar DRY en proyectos Android?

En Android, DRY se aplica mediante version catalogs (libs.versions.toml), clases base comunes para adaptadores, fábricas de ViewModel y extensiones utilitarias de Kotlin. Se recomienda extraer la lógica de negocio en módulos compartidos (KMM) y usar View Binding para eliminar la duplicación de findViewById.

¿Cómo aplicar DRY en proyectos iOS?

En iOS, DRY se logra mediante protocolos con implementación predeterminada, configuraciones de red compartidas (NetworkConfig), fábricas de celdas UICollectionView y paquetes SPM con lógica de negocio común. Las extensiones de tipos estándar (Date, String, URL) reducen la duplicación en formato y validación.

Resumen

  • DRY (Don't Repeat Yourself) es el principio de almacenar cada elemento de conocimiento una vez en un sistema, formulado en el libro “The Pragmatic Programmer.”
  • La duplicación de código es la principal fuente de deuda técnica, aumentando el costo de los cambios y el riesgo de errores.
  • Copy-paste sin refactorización lleva a copias divergentes y cambios no sincronizados cuando se modifican los requisitos.
  • La regla de tres es una guía práctica: abstrae el código solo después de que haya aparecido en tres lugares.
  • La composición es preferible a la herencia para eliminar la duplicación en proyectos móviles.
  • Los version catalogs (libs.versions.toml) centralizan la gestión de dependencias en Android y reducen los conflictos en un 52%.
  • La abstracción prematura es más dañina que la duplicación: no abstraigas coincidencias sintácticas aleatorias; distínguelas de la duplicación sistemática de conocimiento.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también