Arquitectura de MVC

A medida que los navegadores modernos se vuelven más potentes con funciones enriquecidas, compilar aplicaciones web completas en JavaScript no solo es factible, sino que cada vez es más popular. Según tendencias de HTTP Archive, el tamaño del código JavaScript implementado aumentó un 45% en el transcurso del año.

Tamaño de transferencia JS y solicitudes JS

Debido al aumento de la popularidad de JavaScript, nuestras aplicaciones del cliente son mucho más complejas que antes. El desarrollo de aplicaciones requiere la colaboración de varios desarrolladores. Escribir código mantenible y reutilizable es fundamental en la nueva era de las aplicaciones web. La app de Chrome, con sus amplias funciones del cliente, no es la excepción.

Los patrones de diseño son importantes para escribir código que se pueda mantener y reutilizar. Un patrón es una solución reutilizable que se puede aplicar a problemas habituales en el diseño de software (en nuestro caso, la escritura de apps de Chrome). Recomendamos que los desarrolladores separen la app en una serie de componentes independientes que sigan el patrón MVC.

En los últimos años, se desarrollaron una serie de frameworks de MVC de JavaScript, como backbone.js, ember.js, AngularJS, Sencha y Kendo UI, entre otros. Si bien todas tienen sus ventajas únicas, cada una sigue algún tipo de patrón MVC con el objetivo de alentar a los desarrolladores a escribir código de JavaScript más estructurado.

Descripción general del patrón de MVC

MVC ofrece beneficios arquitectónicos en comparación con JavaScript estándar: te ayuda a escribir un código mejor organizado y, por lo tanto, más fácil de mantener. Este patrón se usó y probó ampliamente en varios lenguajes y generaciones de programadores.

La MVC se compone de tres componentes:

controlador-vista-modelo

Modelo

El modelo es donde se almacenan los objetos de datos de la aplicación. El modelo no sabe nada sobre las vistas ni los controladores. Por lo general, cuando un modelo cambia, se notificará a sus observadores que se produjo un cambio.

Para entender esto más a fondo, usemos la app de listas de tareas pendientes, una app web sencilla de una página que realiza un seguimiento de tu lista de tareas.

controlador-vista-modelo

Aquí, el modelo representa los atributos asociados con cada elemento de la lista de tareas pendientes, como la descripción y el estado. Cuando se crea un nuevo elemento de tareas pendientes, se almacena en una instancia del modelo.

Ver

La vista es lo que se presenta a los usuarios y la forma en que estos interactúan con la app. La vista se crea con HTML, CSS, JavaScript y, a menudo, plantillas. Esta parte de tu app de Chrome tiene acceso al DOM.

Por ejemplo, en la app web de la lista de tareas pendientes anterior, puedes crear una vista que presente de manera atractiva la lista de tareas pendientes a los usuarios. Los usuarios también pueden ingresar un nuevo elemento de tareas pendientes a través de algún formato de entrada. Sin embargo, la vista no sabe cómo actualizar el modelo, ya que es el trabajo del controlador.

Controlador

El controlador es quien toma las decisiones y es la unión entre el modelo y la vista. El controlador actualiza la vista cuando cambia el modelo. También agrega objetos de escucha de eventos a la vista y actualiza el modelo cuando el usuario manipula la vista.

En la app web de la lista de tareas pendientes, cuando el usuario marca un elemento como completado, el clic se reenvía al control. El controlador modifica el modelo para marcar el elemento como completado. Si los datos deben ser persistentes, también realiza un guardado asíncrono en el servidor. En el desarrollo enriquecido de apps web del cliente, como las Apps de Chrome, también es fundamental mantener los datos persistentes en el almacenamiento local. En este caso, el controlador también se encarga de guardar los datos en el almacenamiento del cliente, como la API de FileSystem.

Hay algunas variaciones del patrón de diseño de MVC, como MVP (Model-View-Presenter) y MVVP(Model-View-ViewModel). Incluso con el llamado patrón de diseño de MVC en sí, existe cierta variación entre el patrón de MVC tradicional y la interpretación moderna en varios lenguajes de programación. Por ejemplo, algunos frameworks basados en MVC harán que la vista observe los cambios en los modelos, mientras que otros permitirán que el controlador controle la actualización de la vista. Este artículo no se enfoca en la comparación de varias implementaciones, sino en la separación de preocupaciones y su importancia para escribir aplicaciones web modernas.

Si deseas obtener más información, te recomendamos el libro en línea de Addy Osmani: Learning JavaScript Design Patterns.

En resumen, el patrón MVC ofrece modularidad para los desarrolladores de aplicaciones y permite:

  • Código reutilizable y extensible.
  • Separación de la lógica de vistas de la lógica empresarial.
  • Permiten el trabajo simultáneo de los desarrolladores que son responsables de diferentes componentes (como la capa de la IU y la lógica central).
  • Son más fáciles de mantener.

Patrones de persistencia de MVC

Existen muchas formas diferentes de implementar la persistencia con un framework de MVC, cada una con sus ventajas y desventajas. Cuando escribas las Apps de Chrome, elige los frameworks con MVC y patrones de persistencia que te resulten naturales y se ajusten a las necesidades de tu aplicación.

El modelo tiene su propia persistencia: patrón de ActiveRecord

El patrón ActiveRecord, que es popular en los frameworks del servidor, como Ruby on Rails, y del cliente, como Backbone.js y ember.js, asigna la responsabilidad de la persistencia en el modelo en sí y, por lo general, se implementa a través de la API de JSON.

Una alternativa un poco diferente a tener un modelo que controle la persistencia es introducir un concepto independiente de las APIs de Store y Adapter. El almacenamiento, el modelo y el adaptador (en algunos frameworks se llama proxy) funcionan de forma manual. El almacén es el repositorio que contiene los modelos cargados y también proporciona funciones como crear, consultar y filtrar las instancias de modelo que contiene.

Un adaptador o un proxy recibe las solicitudes de un almacén y las traduce en las acciones adecuadas que se realizarán en tu capa de datos persistentes (como la API de JSON). Esto es interesante en el diseño moderno de la aplicación web porque a menudo interactúas con más de una capa de datos persistentes, como un servidor remoto y el almacenamiento local del navegador. Las Apps de Chrome proporcionan la API de Chrome Storage y la API de fileSystem de HTML5 para el almacenamiento del cliente.

Ventajas:

  • Fácil de usar y entender.

Desventajas:

  • Es difícil de probar, ya que la capa de persistencia está "preparada" en la jerarquía de objetos.
  • Es difícil tener objetos diferentes que usen diferentes almacenes persistentes (por ejemplo, las APIs de FileSystem, la IndexingDB o el servidor).
  • La reutilización del modelo en otras aplicaciones puede crear conflictos, como compartir una sola clase de Customer entre dos vistas diferentes, y cada vista desea guardar en lugares diferentes.

El controlador es persistente

En este patrón, el controlador conserva una referencia al modelo y al almacén de datos, y es responsable de mantener el modelo persistente. El controlador responde a eventos de ciclo de vida como cargar, guardar y borrar, y emite comandos al almacén de datos para recuperar o actualizar el modelo.

Ventajas:

  • Es más fácil de probar y el controlador puede pasarse a un almacén de datos ficticio para escribir pruebas.
  • El mismo modelo se puede volver a usar con varios almacenes de datos con solo construir controladores con distintos almacenes de datos.

Desventajas:

  • El código puede ser más complejo de mantener.

AppController tiene persistencia

En algunos patrones, hay un controlador supervisor que es responsable de la navegación entre un MVC y otro. El AppController decide, por ejemplo, que el botón "Atrás" mueve al cliente de una pantalla de edición (que contiene widgets o formatos de MVC) a una pantalla de configuración.

En el patrón de AppController, este responde a los eventos y cambia la pantalla actual de la app enviando una llamada al almacén de datos para cargar los modelos necesarios y construyendo todas las vistas y los controladores coincidentes para esa pantalla.

Ventajas:

  • Mueve la capa de persistencia aún más arriba en la pila, donde se puede cambiar con facilidad.
  • No contamina los controladores de nivel inferior, como un DatePickerController, con la necesidad de saber sobre la persistencia.

Desventajas:

  • Cada "Página/pantalla" de la app ahora requiere mucho código estándar para escribir o actualizar: Model, View, Controlador y AppController.

MVC es fundamental para diseñar Apps de Chrome. Recomendamos los siguientes frameworks de MVC que cumplen con la CSP para escribir Apps de Chrome seguras y escalables:

Recursos útiles

En línea

Libros