El desarrollo de aplicaciones móviles ha evolucionado mucho en los últimos años. Gracias al interés de los desarrolladores y a la madurez de las plataformas móviles cada vez es más común que los equipos de desarrollo pongan más énfasis e interés en crear componentes reutilizables y utilizar buenas prácticas de desarrollo como ya existe en otras especialidades de desarrollo de software como aplicaciones de escritorio, aplicaciones web y aplicaciones de backend.
Este interés nos ha llevado a que para cada plataforma vayan proliferando cada vez más la aparición de distintos patrones para conseguir un código más testeable, más modularizable y más reutilizable, lo que repercute en mejorar el rendimiento de las aplicaciones, reducir el número de errores y poder crear software de mayor calidad. En este articulo voy a explicar el patrón MVP. 


En Apiumhub siempre nos hemos centrado en crear el software con la mayor calidad posible y sobre todo software que funcione, usando de forma intensiva los patrones y técnicas de desarrollo de software más indicados para cada plataforma e intentando adaptarlos a las necesidades de los clientes y a nuestras propias necesidades de desarrollo.

Vamos a centrarnos en explicar el patrón MVP que ya hemos estado usando en otras plataformas y que está demostrando que se adapta relativamente bien a las tecnologías móviles, como el caso de Android, donde se ha convertido en un standard de facto.

Explicaremos cómo hemos adaptado el patrón MVP al desarrollo de aplicaciones en iOS, cual es nuestra propuesta y las razones por las que creemos que es una alternativa válida a otros patrones y como hemos encajado las diferentes piezas propias del desarrollo en iOS dicho patrón.

El patrón MVP se inventó en los años ‘90 como una iniciativa conjunta en C++ desde Apple, IBM y HP alternativa al patrón MVC. Es un acrónimo de las palabras Model, View y Presenter, que son los componentes esenciales de este patrón. Existen diferentes implementaciones de este patrón y algunas variantes importantes como el Supervising Controller o el Passive View.

La principal diferencia entre el patrón MVP y otros patrones de UI es la completa independencia entre vista y modelo, dicho en otras palabras la vista no sabe que existe un modelo y el modelo no sabe que existe una vista.

En el caso que nos ocupa, en Apiumhub, hemos adaptado una variante de este patrón implementado en un framework denominado Claymore (aquí un ejemplo en C#).

 

El patrón MVP

 

Al igual que todas las definiciones del patrón MVP en nuestro caso este cuenta con 3 partes separadas y claramente diferenciadas pero con algunas particularidades:

 

La Vista

La vista es un layout que se encarga de renderizar la UI y reaccionar a los eventos del usuario. En el caso de iOS, la vista estará compuesta por un Protocol que expone los métodos de los eventos del usuario y de un ViewController que es el encargado de materializar el renderizado de la UI y de capturar los eventos que pasan al siguiente componente del patrón, el presenter.

 

El Presenter

El presenter es el encargado de hacer de conector entre los eventos emitidos por la vista y ‘conectarlos’ con el modelo, concretamente con los servicios del modelo. En Apiumhub entendemos el presenter como una pieza de software que conecta vista con modelo, pero que carece de lógica, todo el estado de los datos de la vista y su comportamiento se maneja en el servicio y es este, a través del presente, nuevamente el que retorna los datos transformados o responde a un evento como corresponda. En iOS normalmente el presenter es una clase que recibe en el método init la vista y el servicio y conecta los métodos necesarios. El presenter se suele invocar en una extensión class del ViewController principal y es en ese momento donde se hace la configuración que sea necesaria.

 

El Modelo

El modelo es el sistema que contiene la lógica de negocio y está formado por diferentes piezas de software dependiendo de la complejidad de la aplicación. En un sistema “orientado a dominio” tendemos a estructurar las capas típicas del DDD táctico, con importantes variaciones debidas a las peculiaridades de cada aplicación front-end. En las aplicaciones móviles, las partes principales del modelo que concebimos en Apiumhub son:

  • Los servicios: que se encargan de invocar la lógica de negocio (de hallarse presente) contenida en los objetos de dominio de la aplicación y si es necesario llamar al la capa repository (o gateway) para acceder a servicios externos o base de datos locales. En el caso de iOS el servicio constará de una clase y un Protocol. La clase contendrá la implementación de los métodos expuestos por el protocolo.
  • Las entidades: que son los objetos de dominio. Contienen lógica de negocio para reflejar los cambios de estado. Es común que estos objetos sean meros DTOs, ya que la lógica propia de las transiciones de estado se tendría que hallar en servidor, pero hay importantes excepciones. Estos objetos preferiblemente no deberían de llegar nunca a la vista, aunque algunas veces se puede hacer alguna excepción cuando se trate de simples conjuntos de datos (DTOs).Utilizaremos clases que representarán las entidades.
  • Los repository: se encargan de llamar a servicios externos (APis u otros servicios) o a bases de datos locales si la aplicación dispone de ellas. Igual que los servicios estarán formados por una clase y un Protocol.
  • DTO o PresentationModel: Estos son los objetos que son devueltos desde el servicio y representan el estado de una vista trás la ejecución de un evento o algún cambio de estado en la aplicación. Normalmente se construyen a partir de una o más entidades o algunas veces pueden coincidir. En este caso, usaremos Structs para llevar a cabo la representación de este tipo de objetos, ya que al representar estados de una vista, no debería existir jerarquía entre ellos.

 

La principal característica de este patrón MVP ‘Puro’ es que el Presenter carece de lógica y actúa de mero conector. Esto posibilita que un presenter actúe como un componente aislado y pueda ser reutilizado en más de una parte de la aplicación. Algunas de las ventajas que nos proporciona esta forma de entender el presenter son:

 

Es un componente que expresa directamente su intención y responsabilidad sin añadir lógica que podría inducir a pensar que realiza más de una tarea simultáneamente

 

El presenter centraliza el flujo de eventos lo que facilita:

  • El debug, en caso contrario se hace bastante más complicado, sobre todo si se utilizan sistemas de binding
  • Es más fácil trazar el origen de los eventos, se conocen a simple vista las relaciones entre un evento y el servicio que se encarga de manejarlo
  • Se evitan las cadenas de eventos ‘escondidos’ al carecer de lógica y manejar el estado de los datos en el servicio
  • El mismo componente se puede reutilizar en varios contextos y con diferentes servicios
  • No necesita estrictamente de test, sobre todo en entornos estáticamente tipados, porque al ser meramente declarativo dificulta la introducción de errores por lógica o cambio de estado de los datos

 

Algunas de las caracteristicas globales que nos aporta este patrón son:

 

  • El estado de los datos se maneja siempre a nivel de modelo, concretamente en la capa de servicio, cuando no en servidor.
  • Se evitan cadenas de eventos, normalmente una interacción de usuario es un evento
  • Al evitar cadenas de eventos, se minimizan las metrallas de llamadas al servidor, ya que la lógica y el estado de los datos se resuelve a nivel de servicio
  • Reducción del acoplamiento y aumento de la cohesión porque cada pieza de software tiene claras sus responsabilidades y fuerza a distribuir la lógica entre modelo y vista, sin intermediarios.
  • Favorece el uso de test unitarios para verificar el correcto funcionamiento de cada pieza de software

 

En resumidas cuentas lo que nos ha permitido esta adaptación del patrón MVP en Apiumhub es poder hacerlo extensible a una mayor variedad de plataformas, crear sistemas más modularizados, con unos componentes que tienen unas responsabilidades claras, lo que permite que la cobertura de test sea mayor y sean más reutilizables.
Gracias a todas estas caracteristicas, desde Apiumhub, creemos que se adapta y cubre correctamente nuestras necesidades, lo que no quita que mantengamos el patrón en evolución continua y lo mejoremos con nuevas características que se van introduciendo en cada plataforma,esto nos permitirá comparar este patrón con otros que ya se están utilizando en las arquitecturas de iOS como Viper, MVVM, Clean Architecture y que trataremos de evaluar en un próximo artículo.

 

Si te ha gustado este artículo, puede que te interese: 

Suscríbete a nuestro newsletter para estar al día de los eventos, meet ups y demás artículos!