Code Smell en el desarrollo móvil: qué es, tipos y principios de corrección

Autor: IT Sectr Publicado: 2026-05-13 Tiempo de lectura: 9 min

Code Smell es un indicador superficial en el código que señala un posible problema en el diseño o la arquitectura de una aplicación. El término fue acuñado por Kent Beck y popularizado por Martin Fowler en el libro “Refactoring: Improving the Design of Existing Code”. Según Martin Fowler, un olor en el código no significa necesariamente un error, pero casi siempre indica la necesidad de refactorización para mejorar la mantenibilidad.

Puntos Clave

  • Code Smell — un indicador superficial de un problema en el código que no es un error pero dificulta el mantenimiento y el desarrollo
  • Long Method — el olor más común: un método que hace demasiado y necesita dividirse en varios
  • Large Class — una clase que viola el Principio de Responsabilidad Única y contiene lógica de diferentes dominios
  • Duplicate Code — fragmentos de código repetidos que requieren corrección en múltiples lugares al modificarse
  • Feature Envy — un método que usa más datos de otra clase que de la suya propia

Qué es Code Smell

Code Smell es una metáfora para referirse a síntomas en el código fuente que con alta probabilidad indican problemas más profundos. El término en sí no tiene una definición formal — es una heurística basada en la experiencia de los desarrolladores. Martin Fowler y Kent Beck sistematizaron por primera vez 22 olores en 1999 en el libro “Refactoring”, y la mayoría de ellos siguen siendo relevantes décadas después.

Es importante entender la diferencia entre Code Smell y un error. Un olor no es un fallo: el código compila, funciona y produce resultados correctos. El problema es que dicho código es difícil de leer, modificar y probar. Con el tiempo, el coste de cada cambio aumenta y la confianza en la corrección de la refactorización disminuye. Las herramientas de análisis estático (SonarQube, Detekt, SwiftLint) detectan automáticamente muchos olores.

La naturaleza heurística de Code Smell significa que no todos los métodos largos deben dividirse, ni todas las clases grandes requieren refactorización. La decisión la toma el desarrollador evaluando el contexto: frecuencia de cambios, criticidad del módulo, planes de desarrollo. Los ingenieros experimentados perciben un olor intuitivamente — el código “huele mal” aunque todas las reglas formales se cumplan.

Principales tipos de Code Smell

Fowler identificó 22 olores agrupados en varias categorías. Para el desarrollo móvil, los más relevantes son los olores estructurales, los olores de diseño orientado a objetos y los problemas específicos relacionados con las limitaciones de la plataforma. Examinemos cada grupo con ejemplos reales.

Olores estructurales

Long Method es el olor más común en las aplicaciones móviles. Una pantalla de formulario de registro suele contener un único método setupUI de 200+ líneas que crea todas las Views, configura las restricciones, se suscribe a eventos y maneja errores. Solución: dividir en métodos por bloques lógicos — configureEmailField, configurePasswordField, setupConstraints, bindViewModel.

Large Class — una Activity o ViewController responsable de la visualización, navegación, lógica de negocio e interacciones de red todo a la vez. Esta clase viola el Principio de Responsabilidad Única y contiene decenas de campos y métodos. En Android, suele ser un Fragment con 1000+ líneas que contiene lógica de diferentes pantallas. Solución: extraer un presentador/ViewModel, mover el código de red a un repositorio y la navegación a un coordinador.

Duplicate Code — copiar bloques idénticos en diferentes partes de la aplicación. Un ejemplo típico: dos pantallas que muestran una tarjeta de producto — en el catálogo y en favoritos. Si la lógica de visualización está copiada, corregir un error en un lugar no lo corregirá en el otro. Solución: extraer la lógica común en un componente reutilizable o extensión.

Olores de diseño orientado a objetos

Feature Envy — un método de una clase usa intensivamente datos de otra clase. En Android, esto se manifiesta cuando una ViewModel accede directamente a los campos de un modelo User en lugar de llamar a un método del modelo. Señal: si un método puede trasladarse a la clase cuyos datos usa — muévalo. Switch Statements (cadenas de condiciones) — una construcción switch o cadena if-else que verifica el tipo de objeto. En su lugar, use polimorfismo o el patrón strategy.

Data Class — una clase que solo almacena datos pero no contiene comportamiento. Las data classes en Kotlin o las estructuras en Swift no son inherentemente un olor. El problema surge cuando la lógica de negocio que trabaja con esos datos está dispersa por toda la base de código en lugar de estar encapsulada. Refused Bequest — una subclase no usa la mayoría de los métodos del padre y los sobrescribe con stubs vacíos. Señal de herencia incorrecta: reemplace la herencia por composición.

Olores en el desarrollo móvil

God Activity / God Fragment — una Activity o Fragment que lo sabe todo: ciclo de vida, datos, navegación, Permisos, DI. Es la clase más costosa de mantener en una aplicación. Solución: los patrones arquitectónicos MVVM, MVI o Clean Architecture separan las responsabilidades. Giant ViewController — el equivalente en iOS, donde un UIViewController contiene toda la lógica de la pantalla y a menudo supera las 500 líneas.

Hardcoded Resources — cadenas, colores, tamaños, URL de API incrustados directamente en el código. En Android, esto viola el sistema de recursos R; en iOS, NSLocalizedString y Asset Catalog. Solución: mover todas las cadenas a strings.xml o Localizable.strings, las URL a un archivo de configuración, los tamaños a dimens. Leaking Context — mantener una referencia a una Activity o ViewController más tiempo del que vive el propio componente. Provoca fugas de memoria y caídas. Solución: referencias débiles, Jetpack Lifecycle, RxSwift DisposeBag.

OlorDónde apareceSolución
Long MethodAndroid/iOSExtract Method, dividir
Large ClassActivity, ViewControllerMVVM, VIPER, Clean Arch
Duplicate CodeCualquier pantallaShared Component, DRY
Feature EnvyViewModel, PresenterMove Method
Leaking ContextAndroidComponentes Lifecycle-aware

Cómo encontrar Code Smell

Code review es la forma más fiable de detectar olores. El ojo humano nota construcciones poco naturales que los analizadores automáticos pasan por alto. La eficacia del code review mejora cuando el equipo usa una lista de verificación de olores típicos. Se recomienda revisar no más de 200–400 líneas de código por sesión — después de este umbral, la atención disminuye y los olores comienzan a pasar desapercibidos.

Análisis estático automatiza la búsqueda de olores estructurales. Para Android, las herramientas estándar son Detekt (Kotlin) y Android Lint; para iOS, SwiftLint y SonarQube. Estas herramientas encuentran métodos largos, clases grandes, código duplicado y muchos otros problemas. Es importante ajustar las reglas al proyecto — las configuraciones predeterminadas suelen ser demasiado estrictas o, por el contrario, pasan por alto olores críticos.

Métricas de código proporcionan criterios objetivos: Complejidad Ciclomática (umbral >10 requiere atención), Líneas de Código por Método (umbral >30), Profundidad de Herencia (>3 — motivo para reflexionar). Herramientas como CodeMetrics (Xcode) y Gradle Metrics Plugin construyen gráficos de cambios de métricas en el tiempo. Si la complejidad de un método creció de 5 a 15 después del último commit — es una señal para refactorizar.

kotlin
// Ejemplo: método con complejidad Ciclomática = 7 (por encima del umbral 5)
fun processOrder(order: Order) {
    if (order.status == Status.NEW) { /* 10 líneas */ }
    else if (order.status == Status.PAID) { /* 15 líneas */ }
    else if (order.status == Status.SHIPPED) { /* 20 líneas */ }
    else if (order.status == Status.DELIVERED) { /* 8 líneas */ }
    else if (order.status == Status.CANCELLED) { /* 5 líneas */ }
    else { throw IllegalStateException() }
}

// Solución: polimorfismo en lugar de switch
interface OrderHandler {
    fun handle(order: Order)
}

La detección automatizada de olores no reemplaza el code review: los analizadores estáticos solo encuentran problemas estructurales pero no capturan olores semánticos (Feature Envy, Inappropriate Intimacy). La combinación de herramientas automáticas y revisión humana da los mejores resultados. Configure su pipeline CI/CD para que las compilaciones fallen cuando se superen los umbrales de complejidad o longitud de método.

Cómo solucionar Code Smell

Refactorización es el método principal para eliminar olores de código. Fowler describe docenas de técnicas de refactorización, cada una aplicable a un olor específico. Extract Method — para métodos largos, Extract Class — para clases grandes, Move Method — para Feature Envy. Es importante realizar la refactorización en pequeños pasos, manteniendo el código funcionando después de cada cambio.

Pruebas antes de refactorizar son obligatorias. Si el código no está cubierto por pruebas unitarias, la refactorización se convierte en una reescritura con resultados desconocidos. Para código heredado sin pruebas, use Characterization Tests — escriba pruebas que capturen el comportamiento actual, luego refactorice. Las pruebas dan confianza de que la lógica de negocio no se ha roto después de la refactorización.

Gradualidad es la clave para solucionar exitosamente los olores en el desarrollo móvil. No intente reescribir una God Activity por completo. Primero extraiga la capa de navegación, luego la capa de datos, luego la lógica de visualización. Cada paso debe ir acompañado de un commit y ejecución de pruebas. Use feature toggles para habilitar la refactorización para un subconjunto de usuarios y revertir si surgen problemas.

  • Extract Method — dividir un método largo en varios cortos con nombres claros
  • Extract Class — extraer un grupo relacionado de campos y métodos en una clase separada
  • Replace Conditional with Polymorphism — reemplazar switch con una jerarquía de clases
  • Introduce Parameter Object — combinar un grupo de parámetros en un objeto
  • Replace Inheritance with Delegation — reemplazar extends por composición

Las herramientas del IDE automatizan muchas técnicas de refactorización. Android Studio e IntelliJ IDEA ofrecen refactorizaciones integradas: Extract Method, Extract Interface, Pull Members Up, Encapsulate Fields. Xcode (a partir de la versión 14) mejoró el soporte de refactorización para Swift. El uso de refactorizaciones automáticas reduce el riesgo de errores en comparación con la copia manual de código.

Code Smell en el desarrollo móvil

El desarrollo móvil añade sus propios olores específicos relacionados con las limitaciones de la plataforma. En Android, esto incluye fugas de Context, cursores sin cerrar y uso incorrecto del Lifecycle. En iOS, ciclos de retención mediante closures, manejo incorrecto de Auto Layout y ViewControllers gigantes. Estos olores no solo perjudican la mantenibilidad sino que también afectan directamente al rendimiento y la estabilidad de la aplicación.

Callback Hell es un olor característico del código que trabaja con operaciones asíncronas. Los callbacks anidados hacen que el código sea ilegible y difícil de depurar. Solución: corrutinas (Kotlin), async/await (Swift 5.5+), RxJava/RxSwift o Combine. Según Google I/O 2023, los proyectos que migraron del estilo callback a corrutinas redujeron la cantidad de errores en un 30% y aceleraron la incorporación de nuevas funciones.

Platform Coupling — acoplamiento fuerte de la lógica de negocio a componentes de la plataforma. Probar dicha lógica requiere iniciar un emulador, lo que ralentiza el ciclo de retroalimentación. Solución: Clean Architecture separa el código en capas Domain (Kotlin/Swift puro sin dependencias de plataforma) y Data/UI (con dependencias de plataforma). La lógica de negocio se prueba en JVM sin emulador.

Preguntas Frecuentes

¿Code Smell es lo mismo que un error?

No — Code Smell no es un error. El código con olor funciona correctamente, pero es difícil de mantener, modificar y probar. Un error es un comportamiento incorrecto; un olor es una advertencia sobre posibles problemas futuros.

¿Cuántos olores identificó Martin Fowler?

22 olores en la segunda edición de “Refactoring” (2019). Entre ellos se encuentran Long Method, Large Class, Primitive Obsession, Data Clumps, Switch Statements, Speculative Generality y otros. La comunidad ha añadido docenas de nuevos olores para paradigmas y plataformas modernos.

¿Qué herramienta es mejor para encontrar Code Smell?

Una combinación da el mejor resultado: Detekt (Android/Kotlin), SwiftLint (iOS), SonarQube (ambas) para análisis automático y code review para olores semánticos. Ninguna herramienta encuentra el 100% de los problemas — la experiencia humana sigue siendo decisiva.

¿Se puede ignorar Code Smell?

, si el código cambia con poca frecuencia o será reescrito completamente pronto. Sin embargo, la acumulación de olores se convierte en deuda técnica: cada nuevo cambio se vuelve más difícil y el coste de reparación crece exponencialmente.

¿Hay olores específicos de SwiftUI y Jetpack Compose?

— los frameworks declarativos han generado nuevos olores: bloques @State gigantes, manejo incorrecto de renderizaciones repetidas, recomposición excesiva y falta de Extracción en vistas separadas. Para SwiftUI, un olor típico es Massive View con docenas de variables @State.

Resumen

  • Code Smell — un indicador superficial de un problema profundo en el código, no un error, pero que reduce la mantenibilidad
  • Long Method y Large Class — los olores más comunes en el desarrollo móvil, que requieren Extract Method y Extract Class
  • Duplicate Code — lógica duplicada que duplica el trabajo con cada cambio
  • Feature Envy y Switch Statements — señales de distribución incorrecta de responsabilidades entre clases
  • Olores específicos — God Activity, Giant ViewController, Leaking Context — únicos de plataformas móviles
  • Refactorización sin pruebas es peligrosa: primero Characterization Tests, luego pasos pequeños con commits
  • Análisis estático (Detekt, SwiftLint) automatiza la detección pero no reemplaza el code review

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