En MVC, ¿pueden varias vistas tener el mismo controlador o una vista debe tener un controlador único?

15

Tengo algunas preguntas al diseñar una arquitectura para un proyecto en torno a MVC. (Es un proyecto de C ++ / Marmalade SDK, no estoy usando ningún marco MVC en particular, estoy haciendo uno).

En varios artículos (como en el artículo original de Steve Burbek ) sigo leyendo el concepto "tríada MVC" que me aturde desde que tomé este concepto literalmente. Cuando lo leí por primera vez, parecía que una aplicación se basaba en unidades de "tríada MVC", una para cada pieza de la interfaz de usuario que supuse, pero encuentro que esto es poco flexible y creo que no es así como MVC estaba destinado a ser utilizado. Luego, investigando más sobre el tema, encontré varios ejemplos de acoplamiento estrecho del controlador y la vista, a saber, relación 1 a 1: TextEditView tiene TextEditController.

Pero cuando vuelvo a mi proyecto, encuentro que podría ser útil tener un controlador (por 'unidad lógica', como AddElementController) y varias vistas para ese controlador en particular.

Claramente estoy pensando en algo como un AddElementController que debería tener algún tipo de pestaña UI. ¿Debo tener un AddElementController que tenga un AddElementTabView y varios AddImageView, AddSoundView, etc. para las pestañas? ¿O debería tener un 'subcontrolador' diferente para cada vista de pestaña?

En resumen, y en relación con el patrón MVC (no la comprensión / implementación particular del marco X de este patrón), ¿es correcto tener varias vistas para un controlador o cada vista debe tener su controlador particular?

Además, ¿es correcto mantener cierta información de estado en el controlador o debe ser sin estado (lo que significa que el estado debe colocarse en algún modelo de estado que no sea de dominio)?

Gracias a todos de antemano.

pedrosanta
fuente

Respuestas:

14

El problema es que el patrón MVC fue diseñado en un sistema que realmente ya no existe. Fue inventado en Smalltalk en un momento en que las bibliotecas de IU no existían. Para crear un diálogo de ventana, dibujó todos los cuadros, resaltó los cuadrados apropiados, se aseguró de que el texto que estaba dibujando terminara en el lugar correcto ... etc.

Imagina cómo sería escribir una aplicación de diálogo utilizando nada más que un lienzo grande. Ese es el mundo del que proviene el MVC.

Una "vista" en este sistema era un cuadro de texto y era una clase responsable de dibujar el cuadro, el texto, dibujar las áreas seleccionadas, responder a los cambios en el texto, etc.

Un "controlador" era otra clase que tomaba eventos del mouse que ocurrían dentro de este cuadro, como el movimiento del mouse, la tecla hacia abajo, la tecla hacia arriba, los clics, etc., y decidiría lo que sucedió. ¿Deberíamos cambiar el texto? ¿Deberíamos cambiar la selección? Cosas como esas.

Un "modelo" era otra clase más que representaba los datos básicos y el estado del componente. Un modelo de cuadro de texto tendría el texto, por supuesto, la fuente, la selección, etc.

Como puede ver, en una situación como esta, los tres componentes están muy enredados en la representación de una sola idea. Tiene sentido en este contexto hablar de una "tríada".

Hoy, si está trabajando en crear una biblioteca de interfaz de usuario y usar comandos de dibujo sin formato, puede hacer algo similar. Pero la aplicación del patrón "MVC" se ha extendido más allá de su propósito inicial. Hoy en día tienes una "vista" que en realidad puede ser un cuadro de diálogo completo, y un controlador que responde a eventos como "textChanged" o "buttonClicked". El modelo en el MVC de hoy es normalmente algo bastante desconectado del sistema (pero generalmente vinculado a la vista al proporcionar una interfaz de observación de algún tipo) y puede haber muchas vistas asociadas con el modelo.

En un sistema que diseñé recientemente, por ejemplo, teníamos más de 10 vistas, todas observando un solo "titular" del documento y su documento activo. Una interfaz de dibujo principal interactuaba con el diseño del documento, varias vistas de propiedades que observaban el elemento seleccionado y proporcionaban una interfaz de registro, y una representación a menor escala de la vista principal que mostraba todo el documento en lugar de solo la ventana visible. Algunas de estas vistas tenían controladores de diversa complejidad que convertían los eventos de la GUI en cambios en el documento, lo que a su vez notificaría sus diversas vistas.

¿Todavía puedes llamar a esa relación una "tríada"? Quizás, pero creo que implica demasiado de la antigua aplicación anterior de MVC.

¿Podría compartir controladores con diferentes vistas? Depende de cuán similares sean las vistas. He descubierto que, en general, este tipo de objeto tiene un comportamiento específico para la vista que está controlando Y el modelo que está manipulando es muy reutilizable ... pero siempre hay excepciones.

Edward extraño
fuente
5

Depende. Hay varias variantes de MVC, algunas donde solo tiene sentido una relación 1: 1 (como "el cuadro de diálogo humilde"), otras donde este no es el caso. Recomendaría leer la serie de artículos " Construya su propio CAB ", explicando las variantes MVC más importantes.

Doc Brown
fuente
3

Las vistas no tienen controladores en MVC. El controlador es el jefe, por lo que un controlador decide qué vista se representará y las vistas no le importa o no le importa qué controlador solicitó la vista.

Puede / tendrá absolutamente múltiples vistas desde un controlador. Solo piense en crear un modelo para cada vista si desea seguir con el patrón MVC.

Mert Akcakaya
fuente
3

El objetivo del controlador es controlar las interacciones del usuario con su modelo de dominio, es decir, es un nivel de indirección entre lo que ve el usuario (la vista) y el estado de sus aplicaciones (el modelo).

Cuando el usuario realiza una solicitud, se dirige a un controlador. El controlador decide cómo transmitir esa solicitud a la aplicación, generalmente a través de algún tipo de clase de servicio. Luego, interpreta la respuesta de esa clase de servicio y decide qué vista enviar al usuario.

Un controlador siempre puede devolver la misma vista (1: 1) si solo hay un tipo de solicitud que el usuario puede hacer del controlador, y siempre requiere el mismo tipo de respuesta. Por ejemplo, HelloWorldControllersiempre se HelloWorldViewmostrará un mensaje "¡Hola, mundo!"

Por otro lado, un controlador a menudo tiene que decidir sobre diferentes vistas, dependiendo de lo que le diga el modelo. El TeamRosterControllerpuede devolver a RugbyTeamRosterViewo a FootbalTeamRosterView, dependiendo del tipo de equipo solicitado.

En general, es preferible que los controladores no tengan estado, aunque puede ser necesario o deseable algún acceso al estado de la sesión del usuario. Debe administrar el acceso a ese estado por separado si es posible.

Recomiendo mirar un marco MVC real para ver qué hace y cómo funciona. No tiene que usarlo, pero definitivamente obtendrá una mejor comprensión antes de construir el suyo.

Matthew Flynn
fuente