Loading Likes...

Hace año y medio que habitissimo sacó la aplicación para profesionales en iOS y Android. Y hace dos lanzó la aplicación enfocada a los particulares también para ambas plataformas.
Al igual que los modelos de negocio de habitissimo han cambiado, las aplicaciones y los desarrolladores han cambiado con ellos. Esto significa muchísimos cambios en la base de código que se te pueden ir de las manos.

En el caso de la aplicación de iOS para particulares que empezó siendo una mínima parte de lo que era la web en estos momentos se está equiparando a pasos agigantados. Desgraciadamente si no se planea bien la arquitectura a seguir desde un principio aparecen los quebraderos de cabeza.

Desarrollando para dispositivos de Apple te das cuenta de que la arquitectura que se sigue mucho, por lo menos al empezar un desarrollo nuevo, es la MVC (Model View Controller). En la teoría es muy bonito pero tiene una gran problemática si lo juntas con las librería de Cocoa de Apple.

En iOS para mostrar una vista necesitas un UIViewController. El nombre engaña un poco por que es a la vez la vista y el controlador de esta. Por lo tanto se tiende a aglutinar todo en una sola clase. Con todo me refiero a las llamadas a la API, la lógica de negocio, el controlar la vista y manipular los modelos. Vamos, un despropósito que para hacer un pequeño proyecto con vistas simples va como la seda, pero ¿qué pasa si una vista tiene que hacer mil cosas?

Un claro ejemplo de esto puede ser el ver una solicitud de presupuestos, desde esta vista puedes modificar la solicitud, puntuar a las empresas que se han apuntado, cancelar la petición, abrir un chat, añadir fotos, etc. Si esto lo tenemos que meter en un solo UIViewController (en nuestro caso BudgetRequestDetailViewController que hereda de UIViewController) nos encontraremos con una clase repleta de métodos que tiene dependencias por todos lados. A esto se le llama MVC (Massive View Controller).

Para evitar estas situaciones una arquitectura muy recomendable es VIPER (View Interactor Presenter Entity Router) que desde habitissimo hemos adoptado con algunas modificaciones.

VIPER se compone de:

  • View: La vista, en este caso el equivalente solo los UIViewControllers
  • Interactor: Contiene la lógica de negocio
  • Presenter: Le pide los datos a los interactors para que la vista los muestre. Y es el encargado de avisar al Router para cambiar de vista o mostrar otra si es necesario.
  • Entity: Son las clases dummy que contienen los modelos
  • Router: Es el encargado de cambiar entre pantallas

Todo esto es muy bonito pero no resolvía todo lo que necesitábamos como las llamadas a la API. Sí, se podrían poner en el Interactor pero éste solo debería tratar la información sin necesidad de saber de dónde obtenerla. Para ello nuestra versión de la arquitectura añade el DataManager que se encarga de proporcionar los datos (tanto desde API como de Caché). También renombramos Entity y le llamamos Model. Por último nos cargamos el Router y delegamos su función al Presenter.

El flujo es muy parecido al de VIPER:

El Presenter puede llamar directamente a uno o varios DataManagers ya que puede ser que la información que necesites no necesariamente tenga que pasar por una lógica de negocio (ejemplo: ver el último email que introdujo el usuario en un campo de texto o la posición en la que estaba antes de cerrar la aplicación). El Presenter también puede llamar a uno o varios Interactors pasándoles una entrada, o no. Éstos realizan una acción u operación y devuelven un resultado al Presenter. Y por último el Presenter pasa la información necesaria al View para mostrársela al usuario.

El Interactor puede llamar a uno o varios DataManager para obtener datos que después de pasarlos por la lógica de negocio se los sirve a otro Interactor o a un Presenter.

El DataManager se encarga de conseguir la información, ya sea desde Caché o API, de forma totalmente trasparente al resto del código.

Además de seguir esta estructura, se pretende que el código sea lo más desacoplado posible inyectando las posibles dependencias. Un ejemplo son que pasaríamos al Presenter todos los Interactor, DataManager y la View.

La arquitectura aquí presentada está siendo adoptada poco a poco en la app para profesionales (Obj-C) y se hizo un refactor completo en la app de particulares (Swift).

Las ventajas de usar una arquitectura como esta son múltiples. Al tener que pasar todas las dependencias es muy fácil de testear. Se puede estructurar fácilmente por módulos y es fácil escalarla. Como punto negativo esto genera un gran número de ficheros. Deberemos crear un mínimo de dos ficheros (ViewPresenter) para mostrar una vista sin lógica de negocio, para una pantalla con algo de lógica de negocio crearemos al menos cinco ficheros (View, Presenter, Interactor, 2 DataManager, y los Models que pertoquen).

Loading Likes...

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *