Ingeniería iOS

[Arquitectura iOS #8] Guía para elegir arquitectura iOS

Si has seguido esta serie de arquitectura iOS hasta aquí, ya tienes todas las opciones sobre la mesa: MVC, MVVM, MVP, VIPER, Clean Architecture, MV y TCA.

5 min de lectura
Imagen de portada de [Arquitectura iOS #8] Guía para elegir arquitectura iOS

Si has seguido esta serie de arquitectura iOS hasta aquí, ya tienes todas las opciones sobre la mesa: MVC, MVVM, MVP, VIPER, Clean Architecture, MV y TCA.

Pero queda la pregunta más difícil. «Entonces, ¿cuál usamos en nuestra app?»

Es cierto que «no hay una respuesta correcta, solo trade-offs», pero eso no basta para decidir. En este último artículo, resumiremos criterios concretos para tomar la decisión.


Criterio 1: tamaño del equipo — la arquitectura es un problema de personas

Primero hay que ajustar el peso de la arquitectura al número de personas, no a la cantidad de código.

En un equipo de 1–2 personas, la velocidad importa más que la uniformidad estructural. En SwiftUI, MV (Model–View) + Repository suele bastar; con UIKit, separar la navegación y la red de MVC también. A esta escala, introducir VIPER (View, Interactor, Presenter, Entity, Router) o TCA (The Composable Architecture) puede hacer que mantener la estructura consuma el tiempo destinado a desarrollar funcionalidades.

A partir de 3–10 personas, el equipo necesita acordar «dónde vive la lógica». MVVM + UseCase/Repository es el estándar más equilibrado en este tramo. Mantener la misma estructura en cada pantalla reduce el coste de las revisiones de código y la incorporación de nuevos miembros.

Con más de 10 personas y varios squads, la uniformidad y los límites de los módulos son prioritarios. Aquí suele elegirse modularización por funcionalidad con capas de Clean Architecture, o TCA como estándar si la complejidad del estado es alta. VIPER y RIBs también se adoptaron en organizaciones de este tamaño.


Criterio 2: vida útil de la app — invierte en límites cuanto más dure

Crear capas para una app de vida corta (un prototipo, un MVP (Minimum Viable Product) de validación o una app para eventos) es un desperdicio. El objetivo es crear rápido y aprender rápido.

Para un producto que vivirá al menos 3 años, la situación cambia. La API del servidor evolucionará, el diseño se rehacerá y habrá migraciones de framework como UIKit→SwiftUI. Lo que realmente compensa no es un patrón llamativo, sino los límites: un Repository que oculte las fuentes de datos y un UseCase que contenga las reglas de negocio. Con límites puedes reemplazar partes; sin ellos, necesitas reescribirlo todo.

Tamaño del equipo, vida útil de la app y complejidad del estado: tres ejes para decidir
Tamaño del equipo, vida útil de la app y complejidad del estado: tres ejes para decidir

Criterio 3: complejidad del estado — el único eje que justifica TCA

Si la app se limita principalmente a «recibir datos del servidor, mostrarlos y enviar las entradas al servidor», MVVM/MV es suficiente. En cambio, si varias pantallas editan el mismo estado a la vez, o se combinan sincronización en tiempo real, fusión offline y un undo complejo, el coste de TCA para controlar estrictamente las rutas de cambio de estado empieza a estar justificado.

Como vimos en el artículo anterior, TCA no es una elección equivocada, sino cara. Si la complejidad de este eje es baja, no podrás recuperar ese coste.


En una sola página

Situación Recomendación
Solo · Prototipo MV (SwiftUI) o MVC + separación mínima
Equipo pequeño · App de servicio general MVVM + Repository (UseCase si hace falta)
UIKit heredado · Alto coste de introducir binding MVP + Coordinator
Organización grande · Producto de larga duración Capas de Clean Architecture + modularización por funcionalidad
Dominio con estado complejo TCA (requiere inversión del equipo en aprendizaje)

Más importante que la tabla es esto: puedes empezar en cualquier casilla y pasar después a la adyacente. Pero para poder hacerlo hace falta una condición.


Invariantes que debes respetar elijas lo que elijas

El principio que atraviesa toda la serie puede resumirse así:

Evita que View toque directamente la red o la base de datos y mantén las reglas de negocio fuera del código de pantalla.

Si se conserva esta invariante, pasar de MVC a MVVM y de MVVM a TCA se reduce a un problema de «sustituir la capa de pantalla». Si se rompe, adoptar cualquier arquitectura de moda acaba en una reescritura completa. El nombre de la arquitectura queda en el currículum, pero los límites son lo que mantiene vivo el producto.

Por último, una migración de arquitectura debe hacerse de forma incremental: empezando por las pantallas nuevas, no de golpe. Rehacer pantallas existentes que funcionan solo por seguir una moda suele terminar en arrepentimiento.

La arquitectura es una herramienta, no un destino
La arquitectura es una herramienta, no un destino

Al terminar la serie

Estas son las ocho entregas resumidas en una frase cada una.

  • MVC: entender la concentración de responsabilidades en UIViewController es el punto de partida
  • MVVM: extraer el estado de pantalla y sincronizarlo mediante binding; sin binding, queda a medias
  • MVP vs MVVM: la diferencia es si el objeto intermedio conoce View
  • VIPER: separación llevada al extremo; su legado sobrevive en Coordinator y UseCase
  • Clean Architecture: las dependencias apuntan solo hacia dentro; empieza por Repository
  • TCA: controlar las rutas de cambio de estado cuando la complejidad justifica el coste
  • El debate sobre MV: lo esencial es dónde vive la lógica y la dirección de las dependencias, no el nombre
  • Guía de elección: elige según tamaño del equipo, vida útil y complejidad del estado; respeta las invariantes y migra gradualmente

La arquitectura es una herramienta, no un destino. Invierte en límites para poder cambiar cuando crezcan el equipo y la app.

Seguir leyendo