Pregunta

Me estoy divirtiendo tratando de entender algunas cosas de MVP, en lo que respecta a los controles de usuario. Estoy usando .NET WinForms (o algo parecido) y el patrón Supervising Controller (bueno, creo que lo estoy :).

El Control de usuario es parte de una aplicación MVP (es la Vista y tiene un Presentador asociado, etc.). El presentador siempre se inicia primero, e inicia los modelos y luego las vistas. La Vista construye su IU, parte de la cual será NUEVA a la UC, que es la Vista.

Ahora el Presentador (formulario) necesita saber sobre el Presentador UC, pero creo que no sabe nada sobre cómo está compuesta la Vista. El presentador del formulario, por ejemplo, no sabe que la UC forma parte de la colección de controles del formulario, ni debería hacerlo.

Además, la experiencia de diseño no debe cambiarse; IOW, el desarrollador de la Vista (formulario) debería poder seleccionar un Control de usuario del cuadro de herramientas y soltarlo en un formulario.

Entonces, a mis preguntas. En primer lugar, ¿son correctas mis suposiciones anteriores? Algo equivocado? ¿Hecho un desastre? WTF estás pensando?

En segundo lugar, ¿es correcto (¿suficiente?) hacer que la vista del formulario invoque la vista UC, y el presentador del formulario invoque al presentador UC y tenga algún mecanismo para decirle a la vista UC cuál es su presentador? Esto rompe mi " Presentador primero " regla, pero no estoy seguro de cómo hacerlo.

Cualquier otra idea, sugerencia, comentario con mucho gusto aceptado.

- nwahmaet

¿Fue útil?

Solución

Un presentador debe considerarse como "estado autónomo" en el nivel de presentación. Esto significa que es responsable de garantizar que la presentación de la vista del estado del modelo esté sincronizada. La razón por la que menciono esto es porque el " patrón " de MVP a menudo se pierde en la vista dogmática de cómo las cosas deberían separarse. Parece que esta es una razón por la cual Martin Fowler decidió intentar aclarar la terminología en torno al patrón MVP .

Mi sabor favorito de MVP es la vista pasiva , por lo que mi respuesta se basa en eso .

Implemento controles de usuario compuestos y formularios muy a menudo usando el patrón de vista pasiva. Existen esencialmente 3 configuraciones diferentes:

  1. Un presentador para todos los controles de usuario en la jerarquía. Acoplar la vista usando una interfaz.
  2. Un presentador para cada control de usuario en el árbol compuesto. Cada presentador principal es responsable de crear instancias e inicializar sus presentadores secundarios. Los controles de usuario se crean en tiempo de diseño y pueden funcionar sin un presentador (sin comportamiento de presentación)
  3. Un presentador para cada control de usuario en el árbol compuesto. Todos los presentadores están acoplados libremente a través de una clase de controlador de nivel superior. La clase de controlador es responsable de construir el presentador, conectarlo y coordinar sus eventos.

Aunque es una solución de último recurso para mí (debido a su complejidad), creo que la última opción es la solución que está buscando.

Otros consejos

He estado enfrentando este problema exacto durante varios meses en una aplicación en la que estoy trabajando. La conclusión a la que he llegado recientemente es que, en muchos casos, podría ser imposible aplicar el patrón MVP tanto en la ventana como en los niveles de control del usuario, sin "romper". el patrón.

Mi opinión al respecto es que el control del usuario es parte de la implementación de la vista, y el presentador no debe saber qué sucede dentro de la implementación de la vista, lo que significa que el presentador a nivel de ventana, por extensión, no debe saber sobre el usuario presentador de control, y por lo tanto no debe haber comunicación entre ellos, incluida la creación de instancias de este último por el primero. Se podría argumentar que el presentador del control de usuario es parte de la implementación de la vista de ventana, por lo que la vista de ventana puede crear una instancia del presentador de control de usuario. Pero no puede inyectar las clases de modelo que necesita el presentador, porque se supone que la vista no las conoce.

La conclusión a la que creo que estoy llegando es que TODOS los controles de usuario son específicos de la implementación de la vista, por lo que deberían estar contenidos completamente dentro del silo de vista del patrón más grande. Como tal, no pueden tener sus propios presentadores ... Al menos no agrupados con la implementación de control en sí. En su lugar, deben ser manipulados indirectamente por el presentador de la ventana principal, a través de los campos de paso expuestos en la interfaz de vista. En resumen, el control de usuario está expuesto al presentador no por su propia interfaz, sino a través de una interfaz de paso común implementada por su vista principal. Llame a esto una "interfaz de vista parcial".

Su presentador puede contener instancias de una clase de sub-presentador reutilizable que solo funciona con esta interfaz de vista parcial y las piezas relevantes del modelo. Esto le permitirá evitar volver a escribir el código del presentador para traducir desde el modelo cada vez que necesite usar el control, Y evita que la vista de ventana necesite saber sobre el modelo para pasar información al presentador del control.

Lo que esto efectivamente hace es separar aún más el control del usuario, como módulo, de su modelo de datos. Esto tiene sentido si piensa en un control de usuario, como un todo, como un elemento de la implementación de la vista. Como unidad reutilizable, es una funcionalidad de vista, y ninguna parte debe estar vinculada a su modelo de datos.

Sus preguntas son generales que podrían aplicarse una variedad de esquemas.

En este caso, supongo que deberías mirar el Patrón de Observador.

Tiene una interfaz que implementaría cualquier cosa que use esa vista. Luego se registraría cuando la aplicación se inicializa con una colección de esas interfaces. Cualquier comando que necesite actualizar esa vista atravesaría la colección notificando que cada vista debería actualizarse.

A diferencia de los ejemplos típicos, las vistas serían controles de usuario. Tiene la flexibilidad de hacer que cualquier elemento de la interfaz de usuario implemente esa interfaz para poder usar diálogos, formularios completos, etc., además de su Control de usuario.

Finalmente recuerde que el Control de Usuario NO es la vista sino la implementación de la Vista. Cualquiera que sea el esquema que adopte, puede definir lo que quiere que sea la Vista tan profunda como desee y que el Control de usuario implemente esa interfaz.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top