Este artículo está enfocado como un repaso, más bien didáctico, sobre uno de los patrones de diseño arquitectónico de software más populares en los últimos años: el Modelo-Vista-Controlador, o MVC. En este texto hablaremos tanto de la teoría detrás del patrón, como algunas de sus implementaciones en diferentes tecnologías.
Arquitectura MVC
Todos los patrones software, por definición, proponen una solución abstracta a un problema abstracto determinado en un contexto específico. La aplicación de un patrón es, por lo tanto, la implementación del patrón teórico en una tecnología concreta.
El patrón de diseño arquitectónico de software Modelo-Vista-Controlador, habitualmente abreviado como arquitectura MVC, se usa desde los años 90 en aplicaciones interactivas de todo tipo. En este caso el contexto son las aplicaciones interactivas [1].
En las aplicaciones interactivas, en las que el usuario introduce datos en una interfaz gráfica para que el sistema manipule y almacene la información, hay una gran proporción de código destinado a programar la interfaz gráfica, y además, normalmente hay una fuerte dependencia entre este código y el código relativo a la lógica de la aplicación [2]. Esta fuerte dependencia conlleva, implícitamente, características no deseables en el software. En ingeniería del software, la dependencia o relación explícita entre diferentes partes del código se llama acoplamiento. Las características no deseables más importantes son:
- Baja reusabilidad del código. Una comprobación de los datos introducidos en una pantalla, está tan vinculada con el código de ésta en concreto, que difícilmente se puede usar desde otra pantalla similar que necesite la misma comprobación. Por consiguiente, hay que volver a programar ese código que no se ha podido reusar por ser demasiado específico.
- Baja mantenibilidad del código. Derivado del punto anterior, al ser necesario programar múltiples veces código similar, cuando se debe realizar un cambio en el código (independientemente de si es una mejora o un bug), hay que reprogramar todas las partes de la aplicación que tienen ese código equivalente.
- Baja cambiabilidad del código. El alto acoplamiento entre la interfaz y la lógica de la aplicación dificulta poder cambiar de interfaz gráfica (o añadir una nueva) sin afectar a la lógica.
Cuando necesitamos modificar el software para cualquier propósito (cosa habitual) y nos encontramos con estas características no deseables, decimos que el software no es de calidad. Los factores de calidad del software están enumerados y definidos por standards de la ingeniería del software [3]. La gravedad de estos problemas depende del tamaño y complejidad de la aplicación: cuanto más grande es, mayores son las dificultades, y en algunos casos implican un esfuerzo (en tiempo y recursos) tan grande que vale más la pena tirar la aplicación y volver a programarla de cero.
La solución que propone el patrón de diseño arquitectónico Modelo-Vista-Controlador es la de descomponer el código en tres componentes [4]:
- Modelo (o núcleo de una aplicación): Encapsula las funcionalidades y los datos del sistema. Es independiente de los mecanismos de presentación de la información (interfaces gráficas) y de interacción con el usuario.
- Vista (o salida de datos): responsable de mostrar la información al usuario final.
- Controlador (o entrada de datos): responsable de gestionar la interacción con el usuario. El usuario interactúa únicamente con controladores, que gestiona los eventos y acciones sobre la interfaz gráfica, traduciéndolos a invocaciones a servicios proporcionados por el Modelo o a peticiones a funcionalidades propias de la Vista.
Nota: resaltar que Modelo, Vista y Controlador son nombres propios, y que en este contexto (arquitectura MVC) tienen exactamente el cometido descrito en este artículo.
En el siguiente diagrama se presenta la interacción entre los tres componentes software, y por lo tanto, su acoplamiento.
Aunque no es evidente a primera vista, la aplicación del patrón implica una metodología que incrementa el coste del desarrollo de la aplicación. Este incremento en el coste del desarrollo siempre ocurre, pero compensa ampliamente las consecuencias de no aplicarlo: solventa los problemas que empeoran la calidad del software. Por otro lado, aplicar un patrón cuando soluciona problemas que no tenía el sistema, sólo incrementa el coste de desarrollo innecesariamente. Es tarea de un arquitecto de software identificar las necesidades de un sistema y aplicar los patrones adecuados sólo cuando sean necesarios.
Arquitectura Web
El mundo de las páginas y aplicaciones Web, al que estamos tan familiarizados, es en el fondo un mundo de aplicaciones distribuidas. Una aplicación distribuida, o sistema distribuido, es un software que se ejecuta de forma distribuida en más de un ordenador. Uno de los paradigmas arquitectónicos de aplicaciones distribuidas es la arquitectura cliente-servidor.
En particular, en el mundo Web, una parte del sistema está en un servidor Web, y la otra en el navegador Web del usuario (cliente). Las dos partes del sistema distribuido se comunican mediante un protocolo de comunicaciones, en este caso HTTP (HyperText Transfer Protocol).
Una característica inherente a todas las aplicaciones distribuidas es que la comunicación entre las diferentes partes no es gratuita. El hecho de enviar información implica que hay un retardo, del medio por el que viajan los datos, lo que se traduce en una pérdida de eficiencia/rendimiento de la aplicación.
Arquitectura MVC en aplicaciones Web
Entonces, si las aplicaciones Web tienen una arquitectura distribuida, y las aplicaciones interactivas suelen usar una arquitectura MVC, ¿cómo distribuimos la arquitectura MVC entre el navegador Web y el servidor Web? ¿dónde pagaremos el peaje de comunicación por tener la aplicación distribuida?
Hay varias posibilidades, cada una con sus pros y contras.
Modelo-Controlador en el servidor, Vista distribuida
Prácticamente todo el sistema está en el lado del servidor, y sólo es la interfaz gráfica la que está distribuida. Es decir, es la Vista la que está partida en dos partes: se crea en el servidor y se envía al navegador. El Controlador y el Modelo están siempre en el servidor. Este es el caso más habitual en páginas Web de puro contenido, o aplicaciones Web con un nivel de interacción bajo (la interfaz no tiene un uso intensivo por parte del usuario al realizar acciones).
También conocidas como full-roundtrip applications, por la secuencia de interacción implícita: el usuario realiza una acción en la interfaz gráfica, se envía la acción al servidor, que instancia al Controlador, resuelve la acción como sea menester, carga los datos del Modelo necesarios para la Vista, que se renderiza en el servidor y se envía (completa) al navegador. Este ciclo se traduce en un refresco completo de los contenidos del navegador por cada una de las acciones del usuario.
La Vista distribuida está implementada mediante HTML.
Modelo en el servidor, Vista-Controlador distribuidos
Una forma de reducir el impacto de la comunicación entre el navegador y el servidor Web, pasa por reducir las llamadas al Controlador del servidor. Para ello, se puede distribuir el Controlador en el navegador, de forma que gestione los eventos y acciones locales en el local, evitando la comunicación con el servidor siempre que sea posible, y manteniendo la parte del Controlador de acceso al modelo en el servidor.
Esta solución, más agradable al usuario, tiene lagunas de seguridad, ya que el Controlador queda parcialmente expuesto (la parte distribuida al navegador). Se puede solventar esta deficiencia de seguridad, realizando controles adicionales en el servidor, lo que encarece ligeramente el desarrollo y empeora el mantenimiento.
Otra mejora aplicable es el refresco parcial de la Vista. Si bien los Vista-Controlador distribuidos mejoran notablemente la experiencia de usuario, implican un aumento en la complejidad de ambos componentes del patrón.
La tecnología que complementa al HTML y permite implementar código para el Controlador en el navegador es principalmente JavaScript, y es habitual usar frameworks como JQuery o Prototype.
Vista-Controlador en el navegador, Modelo distribuido
Desplazar la Vista-Controlador totalmente en el navegador tiene la ventaja de mantener una buena experiencia al usuario, sin la penalización de distribuir la Vista ni el Controlador. En su lugar, se distribuye el Modelo. Existen frameworks, como AngularJS que permiten distribuir el modelo entre servidor y navegador Web con escaso desarrollo añadido. El hecho de tener en el mismo lado de la aplicación tanto la Vista y el Controlador como el Modelo, permite la implementación simple y completa de un MVC con observadores. Como contrapartida, el uso de frameworks tiene una curva de aprendizaje añadida, y es imprescindible implementar medidas de seguridad en la parte servidor del Modelo.
Algunos frameworks que facilitan la implementación de MVC con Modelo distribuido pueden ser AngularJS, Kendo UI o Sencha.
Referencias
[1] Craig Larman. Applying UML and Paterns. An introduction to Object-Oriented Analysis and Design. Prentice Hall, 1998. (Cap. 16). ISBN-13: 007-6092037224. ISBN-10: 0131489062 [2] Pattern-oriented Software Architecture. A System of patterns. Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal. John Wiley & Sons, 1996. ISBN: 978-0-471-95869-7 [3] Enginyeria del software especificació : especificació de sistemes orientats a objectes amb la notació UML. Dolors Costal Costa, M. Ribera Sancho, Ernest Teniente. Edicions UPC, 2003. ISBN: 9788498801071 [4] Enginyeria del software : disseny. Vol. 1, Disseny de sistemes orientats a objectes amb notació UML. Cristina Gómez, Enric Mayol, Antoni Olivé Ramon, Ernest Teniente. Edicions UPC, 2003. ISBN: 8483015404 [5] MVC Architecture. Chromes developer official site. https://developer.chrome.com/apps/app_frameworks