MVC: no es una buena arquitectura para la web

Febrero 17, 2008 at 11:06 am (Evangelios de Dioses de Silicio) ()

¿Alguna vez intentaron encontrar la tuerca correcta para un tornillo en particular en una caja llena de tuercas de diferentes tamaños y tipos? Bueno, así es como se siente el buscar la arquitectura de software apropiada. Algunas veces solo te dan unas pocas tuercas, e incluso si parecen del tamaño apropiado, terminas forzando el tornillo. Así es como se siente usar el patrón MVC para desarrollar sitios web.

¿Por qué es el MVC una mala elección para el desarrollo web? Veamos la historia del MVC.

MVC fue propuesto como una muy buena solución para el desarrollo en Smalltalk de interfaces gráficas en entornos de ventanas. Cada ventana estaba compuesta de una triada MVC. La vista se encargaba del dibujado de mapas de bits, el controlador atendía acciones del mouse y teclado, y el modelo guardaba el estado de la ventana y la información mostrada en ella. Cada vista esta asociada con un controlador y un modelo en su creación. Cualquier modelo podía ser asociado débilmente a cualquier vista, pero cada par controlador/vista siempre se mantenían asociados con su respectiva pareja. En realidad el controlador no se encargaba de manejar la lógica del negocio en la aplicación, su propósito era manejar la interacción del mouse y el teclado, y actualizar la vista acorde, lo cual no era una tarea trivial. El modelo podía ser compartido entre diferentes displays, por eso la necesidad de ser débilmente asociable, una necesidad que aún hoy persiste, pero no así para la asociación modelo/vista, ésta tenía un propósito diferente: el modelo debía poder notificar a las vistas asociadas sobre cambios que ocurrieran fuera de su entorno.

Además, las vistas estaban pensadas para ser incluidas una dentro de otra, o sea, de manera jerárquica (lo que significa que el MVC es por definición jerárquico, realmente no existe tal cosa como el MVC Jerárquico). Una vista de ventana tenía vistas hijo para los botones, campos de texto, menues, etc, y cada vista hija era además parte una tríada MVC.

Hasta acá todo bien. Hoy en día todas las tareas cubiertas por una arquitectura MVC son resueltas en las APIs para interfaces gráficas, y tenemos modelos diferentes para generar interacción con estas interfaces. El manejo de eventos es mayormente usado para agregar lógica que antes era agregada a un controlador concreto, que ahora fue reemplazado por un controlador genérico que envía eventos donde lógica foránea podría ser aplicada. La asociación de flujo de datos (dataflow binding) permite asociar orígenes de datos con el display donde mostrarlos, y se encarga de las dos direcciones del flujo de la información, de manera que el display pueda pedir los datos cuando se genera la vista, y recibir sucesivas actualizaciones cuando la información se modifica. Además, un modelo lazy se puede aplicar de manera que los datos se capturen solo cuando sean necesarios, en lugar de almacenarlos en memoria muy previamente a su uso.

En pocas palabras, MVC no es ya una preocupación del desarrollador de interfaces gráficas (a menos que trabaje en una API de interfaces gráficas).

Entonces, veamos que tan bien se puede exportar el MVC a un entorno diferente. Los sitios web (no hablemos del difuso concepto de “aplicaciones web”, el desarrollo web sigue siendo en su gran mayoría sitios web) son bastante diferentes que las interfaces gráficas de ventanas. Veamos cuales son las diferencias más importantes:

La web no es un entorno de ventanas. Sí, podes tener varias ventanas corriendo un navegador web, pero un sitio web desconoce todo sobre ventanas y no provee una interacción (a priori) entre páginas en diferentes ventanas. En otras palabras, no se supone que sepas que otra página web esta corriendo en otra ventana, o que puedas interactuar con ella. Actualmente es totalmente dejado al navegador el implementar tales cosas, y podrías usar javascript para hacerlo, pero no es para lo cual la web fue pensada, solo alguien pensando fuera de los parámetros habituales.

La web es pasiva. A pesar de que algunos sitios proveen la ilusión de ser activos, la web supuestamente es pasiva, o sea, pedís una página y no recibís sucesivas actualizaciones de la misma hasta que la pidas de nuevo. El desarrollo de sitios web consta mayormente en crear dinámicamente páginas a pedido. Nada ocurre si el usuario no pide una página web. Pero, de nuevo, esto sólo es la base común que comparte el desarrollo web, no significa que alguien pueda crear un sitio web que se actualice activamente y actúe como una aplicación de escritorio, pero sigue siendo solo alguien pensando fuera de los parámetros habituales. La web es solo un repositorio de hipertexto, hasta el día en que cambien los protocolos.

La navegación web carece de estado. Una interfaz de ventanas retiene el estado de sus vistas mientras las navegamos, la web no provee una navegación que retenga el estado. Podes acceder cualquier página web en cualquier momento, y no deberías esperar que, al volver a una página visitada previamente, ésta recuerde el estado en el que se encontraba cuando la visitaste antes. La persistencia y manejo del estado durante de la navegación es una de las mayores preocupaciones del desarrollo de sitios web, y sin importar que tan bien hechos sean los componentes que proveen esto, va a ser un work-around, y seguramente uno que no es aprueba de tontos. Tenemos las cookies para almacenar datos en el cliente, pero no son confiables y proveen capacidades muy limitadas. Además, la mayoría de los intentos de proveer una navegación con persistencia del estado rompen/romperían el mecanismo estándar de navegación que los navegadores proveen (atrás-adelante-historial).

La web está compuesta de muchos tipos de contenidos y en variadas codificaciones. En una web coexisten varios documentos de diferentes tipos, desde HTML, imágenes, hojas de estilo, XML, PDF, películas flash, applets Java, etc. Algunos pueden ser embebidos, algunos no. Algunos requieren ser codificados apropiadamente para ser mostrados adentro de otros, e incluso diferentes codificaciones son usadas dentro del mismo documento. Por ejemplo, adentro de un HTML, un texto plano tiene que ser codificado diferente si es parte del contenido o si está dentro de un atributo de un tag o una URL.

Entonces, ¿cómo estas diferencias hacen del MVC una mala elección para la arquitectura de un sitio web?

MVC fue diseñado para entornos de ventanas. Una página web no es una ventana ni funcional ni estéticamente. Un sistema de ventanas generalmente intenta evitar la sobrecarga de información por ventana, si hay más que mostrar es mejor hacerlo en una nueva ventana. Una página web no tiene otro opción que sobrecargarse de información, un usuario de la web no espera navegar demasiado para encontrar la información que espera. Nadie agregaría el logo, la cabecera, el menu de navegación, el pie de página, la información legal, etc, en cada ventana en un sistema de ventanas, pero en un sitio web… Además, las páginas web son más difíciles de descomponer jerarquicamente, donde los componentes básicos puedan ser manejados por tríadas MVC anidadas. O controlas todo lo que pasa en la página, o controlas todo lo que pasa en la página.

MVC puede manejar displays pasivos pero fue pensado para manejar displays activos. El par modelo/vista está mejor aplicado cuando maneja eventos que ocurren sin la interacción del usuario. Sin esto, se convierte en un pobre sistema de templates. MVC sería una buena opción para una API de interfaces gráficas AJAX hecha en el cliente en javascript, pero para el lado del servidor HTTP, mmmm…. no.

MVC asume que el modelo (estado de la vista) es persistente. Usualmente, las implementaciones MVC para la web proveen modelos para entidades en bases de datos de algún tipo, pero no hay un modelo concreto para la vista, particularmente, no hay almacenamiento del estado de la vista en el modelo. Por la manera en que la navegación ocurre en la web, no tiene sentido almacenar el estado de la vista, ya que sería reseteado con cada nuevo pedido. Podes almacenar algunos estados en la persistencia de la sesión, pero no es confiable (cookies). Además, dada la naturaleza de la web, tener un modelo correspondiente a la vista solo trasladaría la sobrecarga de información de la página al modelo.

MVC asume que la vista es persistente. O sea, la vista no se pierde mientras el controlador atiende a una acción. En la web la vista se pierde con cada acción del usuario: con cada pedido de una pagina web se descarta la pagina anterior y se la reemplaza por la nueva. Se puede argumentar que una aplicación AJAX pudiera circunvencionar esta situación, pero de todas maneras la aplicación AJAX estaría pidiendo datos al web server como si de páginas se trataran. Además, en una aplicación AJAX se pierden muchas de las funcionalidad esenciales de la web.

MVC fue diseñado para un ambiente gráfico común sin codificaciones especiales. Los tipos de contenidos que mostraba un sistema MVC eran solo bitmaps, la web maneja muchos mas tipos de contenidos. Además, no había codificaciones especiales que debían aplicarse según el contexto. El render de páginas web tiene una complejidad diferente que necesita ser manejado por, probablemente, más de un subsistema (la V de MVC sola no alcanza).

Conclusión: MVC no es la mejor opción para el desarrollo web ¿Qué puede usarse en su lugar que no sea el viejo rápido-y-sucio script php?

7 comentarios

  1. kNo dijo:

    “MVC fue diseñado para entornos de ventanas.” ¿Y qué? La idea subyacente es mucho mayor que un simple entorno de ventanas. La separación en las tres capas hace que el desarrollo web sea más simple sin tener que ver nada con las ventanas. ¿Problemas de mente cuadriculada?

    “MVC puede manejar displays pasivos pero fue pensado para manejar displays activos.” Este artículo está escrito en 2008 ¿verdad? Porque parece del 2000. Hoy día la web es completamente interactiva. El modelo MVC se ajusta perfectamente en este sentido y aunque no lo hiciese ¿cual sería el problema?

    “MVC asume que el modelo (estado de la vista) es persistente.” ¿De verdad has navegado alguna vez por internet? Verás, para escribir este blog has necesitado autentificarte. En la siguiente sesión, el servidor ya sabía que estas identificado, no lo has tenido que hacer otra vez. Se han guardado datos en el servidor y en el navegador que hacen la información persistente.

    “MVC fue diseñado para un ambiente gráfico común sin codificaciones especiales.” ¿De nuevo mente cuadriculada? ¿Si una cosa no estaba pensada en sus orígenes para algo no se puede usar? De nuevo decir que aunque la idea pudiese surgir en un entorno determinada, pensar que debe quedarse en él es ser muy estrecho de miras.

    Conclusión: No sabes lo que es la web. No sabes de qué hablas. No has programada nunca una aplicación y menos una aplicación web (si, si, aplicación web, que la web no es solo “un repositorio de hipertexto”).

  2. elhombregris dijo:

  3. Lucas dijo:

    Creo que MVC es la elección predilecta para el desarrollo web, es más creo que hay más desarrollo de aplicaciones web con el patrón MVC que aplicaciones de escritorio con la aplicación del mismo. Por algo existen tantos frameworks que asisten al desarrollo web con el patrón MVC.

    Saludos!

  4. elhombregris dijo:

    @Lucas

    No discuto que MVC sea una opción popular, discuto si su adopción busca realmente solucionar los problemas de la web, si se adapto correctamente desde su espacio de uso original.

    En última instancia también empece a preguntarme si es realmente MVC lo que proponen los frameworks desde RoR en adelante, ya que no son consistentes con el diseño original.

  5. Javier dijo:

    Hola,
    Bueno el análisis, pero no voy a coincidir, MVC esta orientado a “vistas” no ventanas, es mas general de lo que parece, aunque en su momento solo se asociaba a las vistas con las ventanas, ahora ya no es asi, y la arquitectura contempla esto. Sí creo q probablemente haya quedado un poco atrasado o desactualizado si pensamos en todas las posibilidades que hoy tenemos para el desarrollo de aplicaciones web (sobre todo incorporando AJAX), practicamente se pueden lograr aplicaciones casi de escritorio (ExtJS, JQueryUI, etc), y con todo esto, el modelo MVC se ve desbordado. Pero de todas maneras no veo una alternativa mejor y aun sigue siendo efectivo y ordenado, mas si usamos frameworks nuevos como por ejemplo cakephp 1.2 o similiares.

    Saludos.

  6. elhombregris dijo:

    @Javier

    nunca dije que MVC estuviera orientado a tal o cual cosa sino que su propósito original es manejar un entorno gráfico basado en ventanas. Si tuviera que sugerir cual es la orientación del MVC, diría que busca desacoplar la lógica de presentación del modelo de datos, y a su vez también desacoplar la lógica del manejo del input del usuario.

    El problema que planteo con esto es que en un sistema de ventanas se presupone que las ventanas retienen su estado cuando el usuario se dispone a ver otra cosa, y en la web esto no ocurre y tampoco es ni sencillo ni transparente implementar algo que lo simule.

  7. Pablo Aguiar dijo:

    Yo tengo el siguiente problema al utilizar mvc en web:
    La url se utiliza para dar las indiciaciones de que debe hacer el controlador: clase/modelo/variable1/variable2
    (en siempre utilizo url “amigables” para mvc)
    Por ejemplo:
    blog/ver/23 (para ver la novedad 23)
    Pero el problema surje por ejemplo cuando tengo que paginar:
    La paginacion debería ser enviada a una grilla de datos, (que tambien debería seguir el mvc) Pero la grilla de datos esta adentro de una vista por ejemplo….
    O sea: tendria que enviar instrucciones a 2 controladores, uno seria el de la clase blog, y otro el de la grilla que deseo paginar…
    La url “amigable” entonces se transforma en algo muy engorrroso…y la relación entre la url y el controlador se hace muy compleja….(no deseo usar AJAX para paginar el datagrid)

Escribe un comentario