En la entrega sobre VIPER (View·Interactor·Presenter·Entity·Router) mencioné brevemente «RIBs, creado por Uber e inspirado en VIPER». En esta entrega lo veremos en profundidad. En Corea también es conocido como la arquitectura adoptada por Toss.
La clave para entender RIBs es una sola. Todas las arquitecturas tratadas hasta ahora (MVC·MVVM·VIPER·ReactorKit) usaban las pantallas como unidad básica. RIBs abandona esa premisa y divide la app por lógica de negocio, no por pantallas.
La existencia de componentes sin pantalla
RIBs es el acrónimo de Router·Interactor·Builder. Estos tres son obligatorios en cada componente (RIB); Presenter y View se añaden solo cuando hacen falta.
- Interactor: El núcleo de la lógica de negocio, el cerebro del RIB.
- Router: Gestiona el árbol conectando y desconectando RIBs hijos.
- Builder: Ensambla un RIB e inyecta sus dependencias.
- Presenter·View: Opcionales. Solo existen en los RIB que necesitan una pantalla.
Que «View sea opcional» es decisivo. Pensemos en el estado «en viaje» de una app de transporte. Abarca el mapa, la tarjeta con los datos del conductor y la lógica de preparación del pago, pero no es una pantalla concreta. En RIBs se convierte en un RIB sin pantalla, viewless, con RIBs hijos que sí tienen pantalla conectados debajo.
Toda la app se convierte en un árbol de RIBs. Los cambios de estado de la app, como el inicio de sesión o el estado del viaje, son cambios en la forma del árbol. Al cerrar sesión, el RIB LoggedIn se desprende por completo del árbol, junto con sus pantallas y lógica. Gestionar el estado equivale a gestionar el árbol.
¿Por qué solo lo usan las organizaciones muy grandes?
RIBs se diseñó desde el principio para «cuando cientos de personas crean una sola app». Decenas de equipos incorporan código simultáneamente en la app de Uber, y dividir por pantallas no bastaba para crear límites entre equipos: la lógica de varios equipos se mezclaba en una misma pantalla.
Al dividir por RIB, cada equipo posee su propio subárbol de RIBs. Como Builder fuerza los puntos de inyección de dependencias, ni siquiera se puede acceder al interior del RIB de otro equipo. Es la «imposición de límites» de la serie sobre modularización aplicada a nivel de arquitectura.
Toss adoptó RIBs por el mismo motivo. En una superapp con decenas de servicios financieros, convertir cada servicio en un subárbol de RIBs hace explícito cuándo conectarlo y desconectarlo.
Por el contrario, todas estas ventajas se convierten en costes para un equipo pequeño.
Primero, RIBs tiene más boilerplate que VIPER. Un RIB suele generar cuatro o cinco archivos. Por eso Uber también ofrece plantillas de generación de código.
Segundo, la curva de aprendizaje es pronunciada. El equipo debe aprender el diseño del árbol, los momentos de attach/detach y la inyección de dependencias por ámbito para compartir el mismo modelo mental.
Tercero, choca con el pensamiento centrado en pantallas. Las especificaciones suelen definirse por pantalla, pero RIBs divide por estado, así que hay que traducir entre ambos durante el diseño.
¿En qué se diferencia de VIPER?
Por los nombres de sus componentes parece una variante de VIPER, pero la diferencia es fundamental.
| VIPER | RIBs | |
|---|---|---|
| Unidad básica | Pantalla | Lógica de negocio |
| Componente sin pantalla | Imposible | viewless RIB |
| Navegación | El Router cambia de pantalla | El Router conecta y desconecta el árbol |
| Objetivo | Separar las responsabilidades de una pantalla | Separar la propiedad del código por unidad organizativa |
El Router de VIPER responde a «¿cómo pasamos a la siguiente pantalla?», mientras que el Router de RIBs responde a «¿qué componentes de lógica deben estar activos en el estado actual de la app?». El mismo nombre, una pregunta distinta.
Resumen
- RIBs es la arquitectura de Uber para dividir una app en un árbol de unidades de lógica de negocio, no de pantallas.
- Permite RIBs sin pantalla y representa los cambios de estado de la app mediante attach/detach en el árbol.
- Su objetivo es separar la propiedad del código por equipo e imponer límites, por lo que destaca en organizaciones de cientos de personas. Uber y Toss son casos representativos.
- En equipos pequeños, el boilerplate y la curva de aprendizaje superan las ventajas. Como se explicó en la guía de selección de la entrega 8, el tamaño del equipo es el factor principal.
Con esto completamos las piezas de la serie de arquitectura iOS que solo habíamos mencionado. De MVC a RIBs, todas las arquitecturas son respuestas distintas a la misma pregunta: «¿Dónde debe ubicarse la lógica?»
Seguir leyendo
Serie de arquitectura iOS
- Artículo anterior: [Arquitectura iOS #9] Resumen de ReactorKit: el estándar de la arquitectura unidireccional
- Artículo anterior: [Arquitectura iOS #8] Guía para elegir una arquitectura iOS: tamaño del equipo, vida útil de la app y complejidad del estado
- Artículo anterior: [Arquitectura iOS #7] Introducción a TCA (The Composable Architecture): guía completa del flujo de datos unidireccional

![Imagen de portada de [Arquitectura iOS #10] RIBs de Uber: dividir la app por lógica de negocio](/assets/images/posts/f06929f4-621d-40e7-88d9-8817b02ef56d/uber-ribs-architecture-hero-1.jpg)