He usado MVP y MVC en el pasado, y prefiero MVP ya que controla el flujo de ejecución mucho mejor en mi opinión.
He creado mi infraestructura (clases de almacén de datos / repositorio) y las uso sin problemas al codificar datos de muestra, por lo que ahora me estoy moviendo a la GUI y preparando mi MVP.
Sección a
He visto a MVP usar la vista como punto de entrada, es decir, en el método del constructor de vistas crea el presentador, que a su vez crea el modelo, conectando los eventos según sea necesario.
También he visto al presentador como el punto de entrada, donde se crean una vista, modelo y presentador, a este presentador se le da una vista y un objeto modelo en su constructor para conectar los eventos.
Como en 2, pero el modelo no se pasa al presentador. En cambio, el modelo es una clase estática donde se llaman métodos y se devuelven respuestas directamente.
Sección B
En términos de mantener la vista y el modelo sincronizados que he visto.
Siempre que cambie un valor en la vista, es decir,
TextChanged
evento en .Net / C #. Esto activa un elementoDataChangedEvent
que se pasa al modelo para mantenerlo sincronizado en todo momento. Y cuando el modelo cambia, es decir, un evento de fondo que escucha, la vista se actualiza mediante la misma idea de generar unDataChangedEvent
. Cuando un usuario desea confirmar los cambios,SaveEvent
se activa y pasa al modelo para guardarlos. En este caso, el modelo imita los datos de la vista y procesa acciones.Similar a # b1, sin embargo, la vista no se sincroniza con el modelo todo el tiempo. En cambio, cuando el usuario quiere confirmar los cambios,
SaveEvent
es despedido y el presentador toma los últimos detalles y los pasa al modelo. en este caso, el modelo no conoce los datos de las vistas hasta que se requiere que actúe sobre ellos, en cuyo caso se pasan todos los detalles necesarios.
Sección C
Visualización de objetos comerciales en la vista, es decir, un objeto (MyClass) no datos primitivos (int, double)
La vista tiene campos de propiedad para todos sus datos que se mostrarán como objetos de dominio / negocios. Tal como
view.Animals
expone unaIEnumerable<IAnimal>
propiedad, aunque la vista los procese en Nodos en un TreeView. Luego para el animal seleccionado se expondríaSelectedAnimal
comoIAnimal
propiedad.La vista no tiene conocimiento de los objetos de dominio, expone la propiedad solo para los tipos de objetos incluidos primitivo / framework (.Net / Java). En este caso, el presentador pasará un objeto adaptador al objeto de dominio, luego el adaptador traducirá un objeto comercial dado a los controles visibles en la vista. En este caso, el adaptador debe tener acceso a los controles reales en la vista, no cualquier vista, por lo que se acopla más estrechamente.
Sección D
Múltiples vistas utilizadas para crear un solo control. es decir, tiene una vista compleja con un modelo simple como guardar objetos de diferentes tipos. Puede tener un sistema de menús a un lado con cada clic en un elemento que muestra los controles apropiados.
Crea una vista enorme, que contiene todos los controles individuales que se exponen a través de la interfaz de vistas.
Tienes varias vistas. Tiene una vista para el menú y un panel en blanco. Esta vista crea las otras vistas requeridas pero no las muestra (visible = false), esta vista también implementa la interfaz para cada vista que contiene (es decir, vistas secundarias) para que pueda exponerse a un presentador. El panel en blanco se llena con otras vistas (
Controls.Add(myview)
) y ((myview.visible = true
). Los eventos generados en estas vistas "secundarias" son manejados por la vista principal, que a su vez pasa el evento al presentador, y viceversa para proporcionar eventos a elementos secundarios.Cada vista, ya sea la vista principal principal o secundaria, está conectada a su propio presentador y modelo. Literalmente, puede soltar un control de vista en un formulario existente y tendrá la funcionalidad lista, solo necesita conectarse a un presentador detrás de escena.
Sección E
Si todo tiene una interfaz, ahora, según la forma en que se haga el MVP en los ejemplos anteriores, afectará esta respuesta, ya que podrían no ser compatibles.
Todo tiene una interfaz, la vista, el presentador y el modelo. Cada uno de estos obviamente tiene una implementación concreta. Incluso si solo tiene una vista concreta, modelo y presentador.
La Vista y el Modelo tienen una interfaz. Esto permite que las vistas y los modelos difieran. El presentador crea / recibe objetos de vista y modelo y solo sirve para pasar mensajes entre ellos.
Solo la Vista tiene una interfaz. El modelo tiene métodos estáticos y no se crea, por lo que no se necesita una interfaz. Si desea un modelo diferente, el presentador llama a un conjunto diferente de métodos de clase estática. Siendo estático, el modelo no tiene ningún enlace con el presentador.
Pensamientos personales
De todas las diferentes variaciones que he presentado (la mayoría probablemente las he usado de alguna forma) de las cuales estoy seguro de que hay más. Prefiero A3 porque mantiene la lógica de negocios reutilizable fuera de solo MVP, B2 para menos duplicación de datos y menos eventos que se disparan. C1 por no agregar en otra clase, seguro que pone una pequeña cantidad de lógica no comprobable en la unidad en una vista (cómo se visualiza un objeto de dominio) pero esto podría revisarse en código o simplemente verse en la aplicación. Si la lógica fuera compleja, estaría de acuerdo con una clase de adaptador, pero no en todos los casos. Para la sección D, creo que D1 crea una vista que es demasiado grande al menos para un ejemplo de menú. He usado D2 y D3 antes. El problema con D2 es que tiene que escribir mucho código para enrutar eventos hacia y desde el presentador a la vista secundaria correcta, y no es compatible con arrastrar / soltar, cada nuevo control necesita más cableado para admitir el único presentador. D3 es mi opción preferida, pero agrega aún más clases como presentadores y modelos para lidiar con la vista, incluso si la vista es muy simple o no necesita ser reutilizada. Creo que una combinación de D2 y D3 se basa mejor en las circunstancias. En cuanto a la sección E, creo que todo lo que tiene una interfaz podría ser excesivo. Ya lo hago para objetos de dominio / negocios y, a menudo, no veo ninguna ventaja en el "diseño" al hacerlo, pero ayuda a burlarse de los objetos en las pruebas. Personalmente, vería E2 como una solución clásica, aunque he visto E3 utilizado en 2 proyectos en los que he trabajado anteriormente. Creo que una combinación de D2 y D3 se basa mejor en las circunstancias. En cuanto a la sección E, creo que todo lo que tiene una interfaz podría ser excesivo. Ya lo hago para objetos de dominio / negocios y, a menudo, no veo ninguna ventaja en el "diseño" al hacerlo, pero ayuda a burlarse de los objetos en las pruebas. Personalmente, vería E2 como una solución clásica, aunque he visto E3 utilizado en 2 proyectos en los que he trabajado anteriormente. Creo que una combinación de D2 y D3 se basa mejor en las circunstancias. En cuanto a la sección E, creo que todo lo que tiene una interfaz podría ser excesivo. Ya lo hago para objetos de dominio / negocios y, a menudo, no veo ninguna ventaja en el "diseño" al hacerlo, pero ayuda a burlarse de los objetos en las pruebas. Personalmente, vería E2 como una solución clásica, aunque he visto E3 utilizado en 2 proyectos en los que he trabajado anteriormente.
Pregunta
¿Estoy implementando MVP correctamente? ¿Hay una manera correcta de hacerlo?
Leí el trabajo de Martin Fowler que tiene variaciones, y recuerdo que cuando comencé a hacer MVC, entendí el concepto, pero originalmente no pude averiguar dónde está el punto de entrada, todo tiene su propia función, pero controla y crea el original. conjunto de objetos MVC.