Tengo una aplicación que usa MVC, pero estoy luchando un poco sobre cómo se debe diseñar el controlador. Por ejemplo, la Vista solo está viendo un subconjunto de los datos del modelo a la vez. Sin embargo, no estoy seguro de cómo exactamente se debe organizar. ¿Es normal que la Vista o el Modelo invoquen directamente funciones en el Controlador, por ejemplo? ¿A través de algún tipo de interfaz? ¿O están totalmente encapsulados y nunca saben sobre el controlador o entre ellos?
Solo como una edición; Esta es una aplicación personalizada que no está escrita en ningún marco web, por lo que no estoy buscando detalles específicos del marco aquí y tengo la libertad de hacer mi propia elección.
Respuestas:
El controlador controla el flujo de actividad. El usuario realiza esta acción, el controlador pasa los datos de la vista al dominio que hace lo que sea necesario y luego, en función de las respuestas, el controlador le dice al marco qué vista mostrar a continuación (y le da suficientes datos para hacer entonces).
Por lo tanto, el controlador debe estar acoplado al modelo de dominio, hasta cierto punto. es decir. Podría poner una capa de servicio en el medio pero, por definición estricta, se convierte en parte del dominio.
También está acoplado a los datos de la vista, pero no a la vista en sí. es decir. simplemente dice "mostrar la vista del cliente utilizando estos detalles del cliente". El marco luego decide dónde debe encontrar esa vista.
Ahora esto debería permitirle desacoplar el modelo de dominio de la vista, utilizando un modelo de vista de los mismos datos. Algunos desarrolladores hacen esto, otros no, y creo que es en gran medida una cuestión de preferencia personal.
En Rails, se le recomienda que empuje los objetos de dominio (ActiveRecord) a la vista y confíe en que la vista no aprovecha ese acceso (por ejemplo, no debe llamar a customer.save desde la vista, aunque estaría disponible).
En el mundo .NET, tendemos a reducir el riesgo al no permitir cosas que no deberían suceder y, posiblemente por esa razón, me parece que el modelo de vista separada es más popular.
fuente
Nota: Robert C. Martin (también conocido como tío Bob) explica esto de una manera mucho mejor y humorística en su discurso principal, Architecture the Lost Years . Un poco largo pero enseña muchos buenos conceptos.
tl; dr: No pienses y planifiques tu aplicación en términos de MVC. El marco MVC es solo un detalle de implementación.
Lo más confuso de MVC es que los desarrolladores intentan usar todos los componentes pegados.
Intente pensar en los términos de un programa, no en los términos del marco.
Tu programa tiene un propósito. Toma algunos datos, hace cosas con datos y devuelve algunos datos.
De esa manera,
controller
es el mecanismo de entrega de su programa.$user->addToCart($product)
addToCart
función deluser
objeto en este caso) hace el trabajo que está destinado a hacer y devuelve una respuesta (digamossuccess
)view
: por ejemplo. en el objeto controlador$this->render($cartView('success')
De esta manera, los controladores se desacoplan del programa y se utilizan como mecanismo de entrega. No saben cómo funciona su programa, solo saben qué parte del programa debe llamarse para las solicitudes.
Si desea utilizar otro marco, su aplicación no necesitará un cambio, solo tendrá que escribir controladores relevantes para llamar a su programa para solicitarlo.
O si desea hacer una versión de escritorio, su aplicación seguirá siendo la misma, solo tendrá que preparar un mecanismo de entrega.
Y el
Model
. Piense en ello como un mecanismo de persistencia.En la forma OO, hay objetos en su programa que contienen los datos.
Cuando agrega un producto al carrito de compras, puede agregar el
product::id
aluser::shoppingCart
.Y cuando desee conservar los datos, puede usar la
model
parte del marco, que generalmente consiste en usar un ORM, para asignar las clases a las tablas de la base de datos.Si desea cambiar el ORM que usa, su programa permanecerá igual, solo cambiará la información de mapeo. O si desea evitar las bases de datos, puede escribir los datos en archivos de texto sin formato y su aplicación seguirá siendo la misma.
Entonces, escribe tu programa primero. Si está programando con la forma 'OO', use objetos simples del lenguaje. No pienses en términos de MVC al principio.
fuente
MVC
es. Por eso escribíMVC Framework
.Martin Fowler hace un buen trabajo al describir el paradigma MVC. Aquí hay un enlace a su artículo sobre él http://martinfowler.com/eaaDev/uiArchs.html
Tenga en cuenta su cita sobre la presentación separada "La idea detrás de la presentación separada es hacer una división clara entre los objetos de dominio que modelan nuestra percepción del mundo real y los objetos de presentación que son los elementos de la GUI que vemos en la pantalla".
fuente
Aquí hay un ejemplo simple de cómo MVC se puede usar en una aplicación Java Swing típica ...
Digamos que tiene un Panel que contiene un Botón y un Campo de Texto. Cuando se presiona el botón, se dispara un evento, lo que lleva a algún cambio de estado en la aplicación. Una vez que se registra el cambio de estado, TextField se deshabilita.
Este, entonces, sería el enfoque típico adoptado por una simple aplicación MVC ...
El controlador se registra como el oyente de los eventos de la vista. Cuando se hace clic en el Botón, la Vista en sí no maneja el evento; el controlador lo hace. El controlador es específico de Swing ya que debe tratar con eventos relacionados con Swing.
El Controlador recibe esta notificación y debe decidir quién debe manejarla (La Vista o el Modelo). Dado que este evento cambiará el estado de la aplicación, decide enviar la información al Modelo, quien es responsable de los datos y la lógica del programa. Algunos cometen el error de colocar la lógica del programa en el controlador, pero en OOP, los modelos representan datos y comportamiento. Lea a Martin Fowler sobre su versión de esto.
El modelo recibe el mensaje en el contexto adecuado. Es decir, no tiene ninguna referencia a Swing ni a ninguna otra referencia específica de GUI. Este mensaje le habla al Modelo y SOLO al modelo. Si se encuentra importando declaraciones javax.swing en el Modelo, no está codificando el Modelo correctamente.
Luego, el Modelo establece su estado en 'deshabilitado' y procede a notificar a las partes interesadas sobre este cambio de modelo. The View, al estar interesado en este evento, ya se ha registrado como Observador de cualquier cambio de modelo. Una vez que la Vista recoge el evento de cambio de estado del Modelo, procede a deshabilitar su TextField. También es legal que la Vista obtenga información de solo lectura directamente de su Modelo sin tener que pasar por el Controlador (generalmente a través de una interfaz específica expuesta por el Modelo para dicha actividad)
Al promover un acoplamiento tan suelto entre la presentación y la lógica empresarial y las capas de datos, encontrará que su código es mucho más fácil de mantener. A medida que los sistemas crecen, también lo hará su enfoque de MVC. Por ejemplo, Hierarchical MVC es una extensión que se usa a menudo para vincular triadas MVC para formar grandes sistemas de toda la empresa sin acoplar subsistemas
fuente
El acoplamiento (el tipo que desea evitar) implica una dependencia mutua entre dos clases. Es decir, un Foo depende de un Bar y un Bar depende de un Foo, por lo que realmente no puede modificar uno sin modificar el otro. Eso es algo malo
Sin embargo, no puedes evitar tener ALGUNAS dependencias. Las clases tienen que saber un poco el uno del otro, de lo contrario nunca se comunicarían.
En el patrón MVC, el controlador controla la comunicación entre el modelo de dominio y la vista de presentación. Como tal, el Controlador debe saber lo suficiente sobre el Modelo para pedirle que haga lo que se supone que debe hacer. El Controlador también debe saber lo suficiente sobre la Vista para poder presentarla al cliente o usuarios. Entonces, el controlador del
modelotiene dependencias en ambos. Sin embargo, la Vista puede existir perfectamente bien sin el Controlador: no hay dependencia allí. Del mismo modo, el modelo no depende del controlador, simplemente es lo que es. Finalmente, el Modelo y la Vista están completamente separados el uno del otro.Esencialmente, el controlador es el nivel de indirección que desacopla la vista del modelo, para que no tengan que conocerse entre sí.
fuente
En mi experiencia, en general, el modelo solo depende de una vista, no específica, a menudo como observador ... si tiene algún tipo de acoplamiento.
La vista generalmente se acopla a lo que sea que esté mirando, lo que tiene sentido. Es difícil encontrar una vista que se pueda desacoplar de lo que está viendo ... pero a veces puedes tener un acoplamiento parcial o algo así.
El controlador a menudo tiende a acoplarse a ambos. Esto también tiene sentido, ya que su trabajo es convertir los eventos de vista en cambios de modelo.
Por supuesto, esta es solo una tendencia que he observado y realmente no dice nada sobre ningún ejemplo específico.
Para comprender qué es MVC y cuál es la relación de acoplamiento, debe analizar cómo surgió MVC. El entorno en el que se creó MVC era uno en el que no existían los "widgets" como elementos de formulario con los que puede crear diálogos. Una "vista" era una caja y dibujaba cosas. Una vista de texto sería un cuadro que dibujaría texto. Una vista de lista era un cuadro que dibujaría una lista. El "controlador" recibió todos los eventos de mouse y teclado del sistema UI que tuvieron lugar en esa vista; no hubo eventos "textChanged" o "selectionChanged". El controlador tomaría todos estos eventos de bajo nivel y generaría interacción con el modelo. El modelo, al ser modificado, notificaría sus puntos de vista; desde entonces hemos llegado a ver esta relación como "observador" y '
ESA es la esencia del patrón MVC. Dado que este tipo de programación de IU de bajo nivel generalmente ya no se realiza, el MVC ha evolucionado en muchas direcciones diferentes. Algunas cosas que llevan ese nombre hoy en día casi no tienen nada que ver con el MVC y realmente deberían llamarse de otra manera. Sin embargo, todavía se puede usar en el sentido de un diálogo como un todo que interactúa con un objeto más grande. Sin embargo, hay muchas mejores alternativas.
Básicamente, todo lo que el MVC estaba destinado a resolver sucede ahora dentro de los widgets y es algo que ya no tenemos que usar.
Para aquellos que piensan que saben mejor:
http://www.codeproject.com/Articles/42830/Model-View-Controller-Model-View-Presenter-and-Mod
http://msdn.microsoft.com/en-us/library/ff649643.aspx
Estoy seguro de que hay más, pero esos son solo los primeros de la lista en google. Como puede ver, el modelo depende en gran medida de una interfaz de vista en MUCHAS implementaciones. Generalmente un modelo es observable y la vista es un observador.
Pero, ¿por qué dejar que los hechos se interpongan en el camino ...
Un artículo ya publicado en otra respuesta también respalda mis declaraciones:
http://martinfowler.com/eaaDev/uiArchs.html
Si la gente quiere seguir diciendo que TODOS en la industria del diseño están equivocados, entonces está bien.
fuente
Si el controlador estaba estrechamente acoplado a una vista, entonces estaremos en un mundo de formularios web. Tendría un código detrás del cual estaría vinculado a un archivo de plantilla (aplicable a los formularios web ASP.NET)
Debido a esto, el controlador no está acoplado a un modelo o una vista. Es solo un mecanismo para procesar solicitudes y enviar respuestas.
La vista está estrechamente acoplada a un modelo. Realice cambios en su modelo (por ejemplo, cambie su propiedad) y tendrá que realizar cambios en su vista.
El modelo no está bien acoplado a una vista. Realice cambios en una vista y esto no afectará a un modelo.
El modelo no sabe nada sobre el controlador o las vistas donde se puede usar. Por lo tanto, el modelo no está estrechamente acoplado a una vista o controlador.
Otra forma de pensar sobre esto:
Realizar cambios en un controlador: la vista y el modelo no se verán afectados
Realizar cambios en un modelo: la vista se interrumpirá ya que depende de un modelo
Realizar cambios en una vista: el modelo y el controlador no se verán afectados
Este acoplamiento suelto en los proyectos MVC es lo que los hace fáciles de probar.
fuente