Compartir a través de


Parte 2: Arquitectura

Un principio clave de la creación de aplicaciones multiplataforma es crear una arquitectura que se preste a la maximización del uso compartido de código entre plataformas. La adhesión a los siguientes principios de la programación orientada a objetos ayuda a crear una aplicación bien diseñada:

  • Encapsulación: garantiza que las clases, e incluso las capas arquitectónicas, solo expongan una API mínima que realiza las funciones necesarias y oculta los detalles de implementación. En el nivel de clase, esto significa que los objetos se comportan como "cajas negras" y que el código que los consume no necesita saber cómo realizan sus tareas. En un nivel arquitectónico, significa implementar patrones, como el patrón de Fachada, que fomentan una API simplificada que organiza interacciones más complejas en nombre del código en capas más abstractas. Esto significa que el código de la interfaz de usuario (por ejemplo) solo debe ser responsable de mostrar pantallas y aceptar la entrada del usuario, y nunca interactuar directamente con la base de datos. Del mismo modo, el código de acceso a datos solo debe leer y escribir en la base de datos, pero nunca interactuar directamente con botones o etiquetas.
  • Separación de responsabilidades: garantiza que cada componente (tanto en el nivel de arquitectura como en el de clase) tenga un propósito claro y bien definido. Cada componente solo debe realizar sus tareas definidas y exponer esa funcionalidad mediante una API que sea accesible para las demás clases que necesiten usarla.
  • Polimorfismo: la programación en una interfaz (o clase abstracta) que admita varias implementaciones significa que el código principal se puede escribir y compartir entre plataformas, a la vez que interactúa con las características específicas de la plataforma.

El resultado natural es una aplicación modelada a partir del mundo real o de entidades abstractas con capas lógicas separadas. Separar el código en capas hace que las aplicaciones sean más fáciles de entender, probar y mantener. Se recomienda que el código de cada capa sea físicamente independiente (ya sea en directorios o incluso proyectos independientes para aplicaciones muy grandes), así como separado lógicamente (mediante espacios de nombres).

Capas de aplicación típicas

A lo largo de este documento y los casos prácticos, hacemos referencia a las seis capas de aplicación siguientes:

  • Capa de datos: persistencia de datos no volátil, probablemente puede ser una base de datos SQLite, pero se podría implementar con archivos XML o con cualquier otro mecanismo adecuado.
  • Capa de acceso a datos: contenedor alrededor de la capa de datos que proporciona acceso CRUD (crear, leer, actualizar, eliminar) a los datos sin exponer los detalles de implementación al autor de la llamada. Por ejemplo, la capa de acceso a datos puede contener instrucciones SQL para consultar o actualizar los datos, pero el código que hace referencia no tendría por qué saberlo.
  • Capa empresarial: (a veces llamada capa de lógica empresarial o BLL) contiene las definiciones de las entidades empresariales (el modelo) y la lógica empresarial. Candidato a modelo de fachada empresarial.
  • Capa de acceso a servicios: se usa para acceder a los servicios en la nube: desde servicios web complejos (REST, JSON, WCF) hasta la recuperación sencilla de datos e imágenes de servidores remotos. Encapsula el comportamiento de redes y proporciona una API sencilla que consumen las capas de aplicación y de interfaz de usuario.
  • Capa de aplicación: código que suele ser específico de la plataforma (generalmente, no compartido entre plataformas) o código específico de la aplicación (no reutilizable normalmente). Una buena prueba para saber si se debe colocar el código en la capa de aplicación o en la capa de interfaz de usuario es (a) determinar si la clase tiene controles de visualización reales o (b) si se puede compartir entre varias pantallas o dispositivos (por ejemplo, iPhone e iPad).
  • Capa de interfaz de usuario (UI): la capa orientada al usuario contiene las pantallas, los widgets y los controladores que los administran.

Es posible que una aplicación no contenga necesariamente todas las capas; por ejemplo, la capa de acceso a servicios no existiría en una aplicación que no tenga acceso a recursos de red. Una aplicación muy sencilla podría combinar la capa de datos y la capa de acceso a datos porque las operaciones son extremadamente básicas.

Patrones comunes de software para dispositivos móviles

Los patrones son una manera establecida de capturar soluciones repetitivas para problemas comunes. Hay algunos patrones clave que es útil comprender en la creación de aplicaciones para dispositivos móviles fáciles de mantener y entender.

  • Modelo-Vista-Modelo de vista (MVVM): el patrón Modelo-Vista-Modelo de vista es popular con marcos que admiten enlaces de datos, como Xamarin.Forms. Se hizo popular con los SDK habilitados para XAML, como Windows Presentation Foundation (WPF) y Silverlight; donde el modelo de vista actúa como una conexión entre los datos (modelo) y la interfaz de usuario (Vista) mediante el enlace de datos y los comandos.
  • Modelo-Vista-Controlador (MVC): un patrón común y a menudo mal entendido, MVC se usa con más frecuencia al crear interfaces de usuario y proporciona una separación entre la definición real de una pantalla de la interfaz de usuario (vista), el motor detrás de ella que controla la interacción (controlador) y los datos que la rellenan (modelo). El modelo es realmente una pieza completamente opcional y, por lo tanto, el núcleo de comprensión de este patrón se encuentra en la vista y el controlador. MVC es un enfoque popular para aplicaciones iOS.
  • Fachada empresarial: también conocida como patrón de administrador, proporciona un punto de entrada simplificado para un trabajo complejo. Por ejemplo, en una aplicación de seguimiento de tareas, es posible que tenga una clase TaskManager con métodos como GetAllTasks(), GetTask(taskID), SaveTask (task), etc. La clase TaskManager proporciona una fachada para los trabajos internos de guardar o recuperar realmente objetos de tareas.
  • Singleton: el patrón Singleton proporciona una manera en la que solo puede existir una sola instancia de un objeto determinado. Por ejemplo, al usar SQLite en aplicaciones para dispositivos móviles, solo querrá tener una instancia de la base de datos. El uso del patrón Singleton es una manera sencilla de garantizar esto.
  • Proveedor: un patrón creado por Microsoft (posiblemente similar a la estrategia o la inserción de dependencias básica) para fomentar la reutilización del código en aplicaciones de Silverlight, WPF y WinForms. El código compartido se puede escribir para una interfaz o una clase abstracta, y las implementaciones concretas específicas de la plataforma se escriben y pasan cuando se usa el código.
  • Asincrónico: no se debe confundir con la palabra clave Async; el patrón asincrónico se usa cuando es necesario ejecutar un trabajo de larga duración sin mantener a la espera a la interfaz de usuario o al procesamiento actual. En su forma más sencilla, el patrón asincrónico simplemente describe que las tareas de larga duración se deben iniciar en otro subproceso (o abstracción similar de un subproceso, como una tarea), mientras que el subproceso actual continúa procesando y escucha una respuesta del proceso en segundo plano y, a continuación, actualiza la interfaz de usuario cuando se devuelven los datos o el estado.

Cada uno de los patrones se examinará con más detalle, ya que su uso práctico se ilustra en los casos prácticos. Wikipedia tiene descripciones más detalladas de los patrones MVVM, MVC, Fachada, Singleton, Estrategia y Proveedor (y, generalmente, de los patrones de diseño).