MVC: mi controlador parece inútil la mitad del tiempo. ¿Es esto un problema?

9

A menudo, cuando diseño un programa con MVC, el controlador es inútil la mitad del tiempo.

Lo que quiero decir es esto: algo sucede en la vista (por ejemplo, un clic de botón). La vista luego notifica al controlador. El controlador luego delega directamente al modelo y no hace nada más porque no tiene nada que hacer.

Por ejemplo:

El usuario presiona el botón 'Color azul'> ver le dice al controlador controller.colorBlue()> el controlador le dice al modelo model.colorBlue()> el modelo colorea algo azul

En este ejemplo, el controlador parece inútil. No agrega nada. La vista bien podría haber hablado directamente con el modelo.

La otra mitad del tiempo, sin embargo, el controlador realiza algún tipo de mediación entre la vista y el modelo.

Mi pregunta es esta: ¿qué tan común es esto en las estructuras MVC? ¿Es razonable que la mitad del tiempo mi controlador parezca innecesario? ¿O es esto un problema? ¿Es esto común? ¿Cómo debería abordar esto?

Si mi pregunta no es lo suficientemente clara, dígalo.

Aviv Cohn
fuente
1
Sin embargo, como lo insinuó RobertHarvey, para este ejemplo en particular, podría ser mejor si controller.colorBlue()realmente llama model.setColor(0, 0, 255);. Una razón para la separación entre Modelo y Vista es que a menudo es el caso de que tenga múltiples elementos de IU para representar un solo estado en el modelo (por ejemplo, un elemento está marcado en el menú, la barra de herramientas está presionada y el puntero cambia a un relleno todo corresponde al campo de herramienta actualmente seleccionado en el modelo), con la separación MVC, el modelo no tendría que preocuparse por sincronizar los diferentes elementos de la interfaz de usuario.
Lie Ryan

Respuestas:

12

Está subestimando la importancia de tener una capa de abstracción entre su interfaz de usuario y su modelo. El controlador cumple esta función el 100 por ciento del tiempo.

Tu ejemplo model.colorBlue()es un poco engañoso. En un modelo real, este probablemente sería un método CRUD. Por lo tanto, su botón podría ser un botón Crear cliente, su método de controlador sería CreateCustomer()y su Modelo sería CreateCustomer(). Claro, solo estás pasando la llamada.

¿Pero qué pasa si necesita cambiar la forma en que funciona el modelo? Si su Vista llamaba directamente a su modelo, su aplicación se interrumpirá si cambia el Modelo. Los métodos del controlador proporcionan un "punto de acceso" para su Vista; puede hacer una modificación simple al método del controlador, tal vez cambiando la llamada del Modelo a CreateCustomerWithVerification(), y todo sigue funcionando.

Se aplica el mismo razonamiento para tener una capa de servicio. En lugar de simplemente tener métodos CRUD en su modelo, debe tener acciones comerciales. De esa manera, mantiene la lógica de negocios fuera de sus controladores y hace posible usar el Modelo en otro lugar, tal vez en una aplicación WPF.

Piense en el controlador como un "patio de maniobras". Debería ser un intermediario, mediando solicitudes entre su UI y su Modelo, pero los métodos de controlador deberían tener la menor lógica posible.

Robert Harvey
fuente
Déjame ver si entiendo lo que estás diciendo. Estás diciendo que incluso si el controlador simplemente delega directamente al modelo, es bueno tener uno entre la vista y el modelo debido a esto: si el modelo cambia, todos los objetos que llaman a sus métodos podrían tener que cambiar. Si la vista es la que llama a los métodos en el modelo, tendrá que cambiar. Si el controlador llama a los métodos, también tendrá que cambiar. Pero la diferencia es que la vista es responsable de mostrar la interfaz de usuario, una parte importante de la aplicación. Sin embargo, la única responsabilidad del controlador es exactamente esto: comunicarse [..]
Aviv Cohn
con el modelo Y debido a esto, es mejor cambiar el controlador cuando cambia el modelo (y dejar la vista igual), luego cambiar la vista.
Aviv Cohn
3
Sí, eso es exactamente correcto. La separación proporcionada por la capa del controlador permite cambios en el modelo sin romper la interfaz de usuario o el enrutamiento.
Robert Harvey
Veo. Y solo para estar seguros: es mejor cambiar el controlador que la vista cuando cambia el modelo, porque la vista es responsable de una lógica importante: mostrar la interfaz de usuario. Cambiarlo teóricamente pone todo su otro código en riesgo. Sin embargo, el único propósito del controlador es exactamente esto: comunicar cosas al modelo y, por lo tanto, depender del modelo, para que la vista no tenga que hacerlo. Y debido a que el controlador no incluye ninguna otra lógica importante, es mejor que el controlador cambie cuando el modelo sí, que la vista que tiene que cambiar. ¿Es esto exacto?
Aviv Cohn
Si, esencialmente. Al aislar dichos cambios en la superficie API del Modelo y los métodos del controlador, proporciona un mejor desacoplamiento de la IU. La Vista nunca debería tener que cambiar como resultado de un cambio que ocurre en la lógica del negocio, a menos que la Vista también necesite reflejar los cambios en la forma en que opera el negocio. Para decirlo de otra manera, la Vista debe tener el menor conocimiento posible de los objetos Modelo; Es por eso que tenemos cosas como ViewModels (que proporcionan un desacoplamiento adicional del Modelo).
Robert Harvey
-1

Mientras codifica, podría pensar de esta manera:

  • ¿Podré cambiar la vista a otra cosa (consola, servicio) o su mismo controlador para una vista diferente?
  • ¿Podré cambiar el modelo para manejar diferentes bases de datos o escribir en algún servicio externo?

En su caso, parece que está poniendo la lógica de dominio en el modelo y eso le causaría problemas si desea cambiarlo: tendrá que copiar métodos como "model.colorBlue" al nuevo modelo.

¿Y qué pasaría si cambia la definición de "azul"? Tendrás que cambiarlo 2 modelos. Además, en el controlador no debe escribir directamente en su base de datos, pero como Lie Ryan señaló , debe usar model.setColor.

Lo mismo con las vistas. Si comienza a poner a la vista la lógica o la validación, si desea cambiar de vista, tendrá que copiar toda esa funcionalidad.

Mantas Karanauskas
fuente