¿Pueden los modelos acceder a las vistas directamente en MVC?

  • Por
MVC es un patrón de diseño susceptible a interpretaciones que producirán diversas implementaciones. En este artículo discutimos acerca de la manera correcta de aplicar MVC en torno a la pregunta ¿Pueden acceder las vistas directamente al modelo?

MVC es un patrón de diseño estructural, que nos indica cómo organizar el código de la aplicación en diferentes "capas", atendiendo a su responsabilidad. No es el objetivo hablar de MVC en plan general, pues ya se hizo anteriormente, sino sobre sus variantes a la hora de implementarlo.

Para ello hemos preguntado a diversos compañeros de la comunidad de DesarrolloWeb.com que nos han dado sus opiniones en base a la experiencia. El objetivo es servir de reflexión a los lectores y hacernos pensar un poco acerca de diversas formas de implementar la separación del código.

La clave no obstante, ya te lo adelantamos, es el "separation of concerns" o la "separación por preocupaciones". Aunque quizás "preocupaciones" que es una traducción literal no se ajuste tan bien como "Responsabilidades" o "intereses". Y es que, a la hora de aplicar MVC encontramos diversas variantes y todas ellas se encargan de separar el código por partes, según la función que realiza cada una.

La separación del código es una de las preocupaciones mayores de los programadores que realmente quieren esforzarse por producir software que sea fácilmente mantenible, escalable, etc. Separamos el código en MVC en lo que son Modelos, Vistas y controladores, pero también es una buena práctica separar código en muchos otros ámbitos, como la creación de objetos y su uso, las validaciones de las operaciones, etc.

Las vistas son más que sistemas de templates

Este es el argumento por el que comenzamos esta discusión y no lo traje yo, sino uno de los estudiantes en un curso que estábamos impartiendo en EscuelaIT.

Las vistas se encargan de mostrar la presentación de los datos de la aplicación. Generalmente en MVC los controladores son los encargados de preparar toda esa información a la vista y luego invocar la vista pasándole todos los datos que se han recabado.

Pero puede haber otras interpretaciones en las que las vistas tengan un poco más de responsabilidad. Por ejemplo, hay programadores que sostienen que las vistas deberían poder acceder directamente a los modelos, para solicitar los datos por ellas mismas.

Si queréis conocer diversos argumentos en cuanto a esta interpretación es interesante la lectura del artículo The View gets its own data from the Model que está salpicado con diversas referencias bibliográficas que lo hacen especialmente confiable. Si tienes un rato no estaría nada mal echarle una lectura, porque se traducirá en un buen ejercicio intelectual dedicado a la programación. Si no tienes tiempo de leerlo, a continuación te hacemos un pequeño resumen:

En el mencionado artículo, el autor hace referencia en numerosas ocasiones a que, según su opinión, la comunidad de PHP ha simplificado demasiado la responsabilidad de la vista, creando código que produce un alto acoplamiento entre los controladores y las vistas. El motivo es que, al necesitar enviarle los datos a la vista, eso produce que tengas un fuerte acoplamiento con la vista. Si quieres reutilizar la vista desde otro controlador además tendrás que repetir el mismo código, para generar esos datos, en todos los controladores que tengan que usar una misma vista.

Son buenos argumentos a favor de ello y no puedo decir que el autor esté totalmente desacertado, sino todo lo contrario, expone muy buenas ideas. Pero le voy a contradecir en dos puntos:

  1. En el MVC más enfocado en sistemas como Java (donde tenemos ventanas, interfaces de usuario, etc.) le encuentro una aplicación muy apropiada, ya que las vistas están "vivas" y cualquier cambio sobre ellas implica cambios en el modelo que deberían ser realizados en el instante. En esos sistemas es necesaria una colaboración estrecha entre la vista y el modelo, pero la programación web es diferente en este sentido y las vistas tienen datos "cocinados en el servidor" y enviados al cliente. Solo cuando se produce una nueva solicitud al servidor se pueden recibir nuevos datos con los que actualizar el modelo. Pero esa nueva solicitud ya implica entrar entrar de nuevo en un ciclo de llamadas entre integrantes de nuestra aplicación, controlador frontal, controladores particulares, modelos y vistas, por lo que no veo tan negativo que la vista deba recibir los datos del controlador, ya que el propio controlador es el que en algún momento gestionará la solicitud.
  2. En la mayoría de casos una acción del controlador produce una salida que está en una vista. Todo lo que rodea a la vista está en un layout, que controlas con el sistema de templates y las vistas suelen ser más específicas para mostrar aquello que es propio a la acción que se está desarrollando en el método del controlador. No veo tan importante la reutilización del código en el caso de la vista en una aplicación web MVC. En mi opinión lo más importante que te ofrecen las vistas son la separación del HTML (generalmente) de la salida, de modo que si tienes que cambiar la presentación no tengas que cambiar todo el código de la lógica de negocio, acceso a datos, etc.

Además, a medida que vas conociendo soluciones propuestas por diversos frameworks te das cuenta que el acoplamiento entre el controlador y las validaciones ya ha sido resuelto en diversas ocasiones y un claro ejemplo son los middleware de Laravel, que se encargan de realizar validaciones para que los controladores no necesiten ocuparse de ellas.

A continuación tienes una serie de notas interesantes sobre este asunto, que están extractadas de conversaciones con colaboradores de DesarrolloWeb.com que nos han ofrecido su visión personal sobre este asunto. En concreto les hicimos la pregunta: ¿Las vistas pueden / deberían pedir los datos directamente al modelo?

Otras separaciones por responsabilidades como MVT

Consultando a nuestra amiga y compañera Eugenia Bahit acerca de esta discusión nos comenta:

En MVC el acceso a los datos no es responsabilidad de las vistas. Las vistas, la única responsabilidad que tienen con los datos es formatearlos al servicio de la interfaz gráfica. El modelo, solo define la base para generar esos datos y el controlador hace el resto.

Esto es lo que uno como programador espera en una arquitectura MVC. Si algo de esto no se respeta, entonces es la app la que pierde mantenibilidad. ¿por qué? Porque si yo, programador externo, quiero modificar la app, buscaré los datos en el controlador. Si allí no los encuentro ¿dónde están? Tendré que recorrer la app para ubicarlos tirando manotazos de ahogado todo el tiempo. Entonces, la app se hace más compleja de mantener.

Sin embargo, en MVT, a falta de controlador, sí son las vistas las que trabajan directamente con los modelos. Django es el ejemplo perfecto (de hecho, incorporaron el concepto de MVT como tal). En MVT, las vistas piden los datos al modelo y los formatean mientras que el modelo hace el resto (define la base que genera los datos, sanea, valida, etc.).

¿Mi opinión profesional al respecto? Me quedo con MVC toda la vida. MVT termina siendo muy desordenado y descuidado en grandes aplicaciones.

¿Mi visión al respecto? La mayoría de las apps (incluso frameworks) hechos con MVC, en realidad implementan las tácticas técnicas de MVT (modelos que definen, sanean y validan datos, controladores que solo definen nombres de recursos, vistas que lo hacen todo). Así que no es nada extraño. Es algo que se ve en el 90% de las apps, es muy común. ¿es lo correcto? No. Pero sí es común.

Yo no comparto que desde las vistas se deba acceder al modelo y me quedo 100% con MVC por una cuestión de que soy 0% pragmática. A mi poco me interesa que algo funcione. Me interesa que sea "perfecto", lo cual es nada pragmático.

En la mayoría de los frameworks y CMS las vistas son "tontas"

Esta es la respuesta que nos ofreció Carlos Ruiz Ruso, compañero que emite con nosotros los #laravelIO.

Segun la filosofia MVC las vistas digamos que son tontas y así es la implementación en los frameworks y CMS que conozco. Si el controlador no le pasa la información no deberían funcionar. Y sería muy extraño que todo el global de los desarrolladores que hacen tan importantes piezas de software estuvieran equivocados.

Por ejemplo, en laravel con Blade, o Prestashop que usar Smarty, a las vistas hay que pasarles la información compilada desde el controlador. Es más, con Smarty ni tan siquiera puedes usar el código de apertura de PHP, por lo que todo lo que manejas deben de ser variables ya prefabricadas. Esa creo es la manera correcta.

¿Quieres desacoplar la vista del controlador? ¿no estás acoplando al modelo?

También preguntamos a nuestro compañero Eduard Tomàs, que tiene un perfil diferente, ya que su especialidad es .NET.

A mi NO me gusta que las vistas accedan a los modelos porque eso acopla la vista con el modelo. Ojo, que ese acoplamiento puede ser distinto en un lenguaje fuertemente tipado (C#, Java) que un lenguaje con duck typing (JavaScript, PHP) pero es un acoplamiento de todos modos.

Prefiero que las vistas sean independientes del modelo y en todo caso estén acopladas a datos que les manda el controlador (llamémosle viewmodel a esos datos). La relación entre vista y viewmodel es, usualmente, 1:1.

Así los controladores hablan con el modelo, lo "mastican" para obtener un viewmodel y ese viewmodel contiene todo lo que necesita la vista y nada más. Cambios en el modelo no afectan a la vista¡ ya que esta está desacoplada.

No hay balas de plata

Esa frase "no hay balas de plata" puede parecer un simple tópico, pero es bastante adecuada a este asunto. La estrategia de unas personas puede ser distinta de la de otras, así como pueden haber aproximaciones a MVC como el mencionado MVT o MVVM, que se adaptan mejor o peor a diversas tecnologías, sistemas, filosofías, etc.

Lo que importa aquí es separar el código por responsabilidades, ya que te facilitará el matenimiento y la reutilización. Hay personas que navegan entre cientos de líneas de código secuenciales y que le resuelven sus problemas, pero lo correcto es separar, por intereses, responsabilidades, etc. Si separas tu código, obtienes los beneficios buscados.

Por otra parte, conviene intentar adaptarse a la filosofía de la mayoría, de modo que sea más fácil que el resto de las personas entiendan tu código y lo puedan modificar sin volverse locos.

Espero que este artículo colaborativo te haya resultado interesante. Cuéntanos tu opinión en los comentarios. Gracias!

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Elia

25/7/2015
patrones de diseño
¿Qué otros patrones de diseño podemos encontrar en el desarrollo web aparte de MVC?
gracias

jagarsoft

07/8/2015
Estupendo debate!!!
Coincido contigo Miguel Angel.
La cosa se complica si le queremos dar a una app web el dinamismo de una desktop con Ajax.
Entonces, el comportamento seria como una app Java, no crees?
De todas formas, prefiero tu aproximacion.

JorgeRD

08/9/2015
abstraer, abstraer, abstraer
En un MVC bien implementado no tiene sentido querer otorgar mas responsabilidades a la vista.
Yo por lo general soy bastante radical en cuanto a separar las cosas y si bien resulta atractivo tener vistas que gestionen sus propios datos les ruego que lo piensen mejor, pues resulta atractivo pero es algo contra-producente y ademas innecesario.
Por ejemplo, si yo tengo una vista que muestra los últimos posts de un forum, y quisiera incluirla en cualquier pagina sin tener que preocuparme por la lógica que carga estos datos seria suficiente con extender la clase controlador, así la clase base gestionaría estos datos. Otro modo seria simplemente empaquetar la lógica que busca esos datos de modo que baste con añadir una linea de código en cualquier controlador.