MVP y WindowsForm

Visto 45 veces
Saltar al primer mensaje no leído

Edgar Ramos

no leída,
27 oct 2010, 15:07:0727/10/10
a altnet-...@googlegroups.com
Gente un saludo

Estoy por desarrollador una app de escritorio, y me surge la duda hay algo parecido a WPF+Caliburn, pero que aplique a WindowsForm, yo que se algo como Claymore (MVP)+WinForm
alguien tiene experiencia en algun framework que soporte MVP, orientado a una app WinForm ?

Muchas gracias por sus comentarios

Saludos
Edgar

 


Cristian Prieto

no leída,
27 oct 2010, 18:22:4627/10/10
a altnet-...@googlegroups.com
Qué tal la serie de "Create your own CAB" de Jeremy Miller? creo que te podría ser de ayuda compañero :)



Cristian Prieto


2010/10/28 Edgar Ramos <eramo...@gmail.com>

 


--
Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a altnet-...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a altnet-hispan...@googlegroups.com
Para tener acceso a más opciones, visita el grupo en http://groups.google.com/group/altnet-hispano?hl=es.

Edgar Ramos

no leída,
27 oct 2010, 18:24:4027/10/10
a altnet-...@googlegroups.com
Gracias Cristian, justo me encontraba visitando esta pagina que me la recomendaron anteriormente

Saludos

Edgar

José F. Romaniello

no leída,
27 oct 2010, 18:39:1527/10/10
a altnet-...@googlegroups.com
Jeremy Miller tiene una wiki con muchos de los patrones de
presentación que el reconoció, muy muy recomendable;
http://www.jeremydmiller.com/ppatterns/MainPage.ashx

En caliburn estan implementados, pero son muy validos para winform

El 27/10/10, Edgar Ramos <eramo...@gmail.com> escribió:

>>> altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsu...@googlegroups.com>


>>> Para tener acceso a más opciones, visita el grupo en
>>> http://groups.google.com/group/altnet-hispano?hl=es.
>>>
>>
>> --
>> Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano"
>> de Grupos de Google.
>> Para publicar una entrada en este grupo, envía un correo electrónico a
>> altnet-...@googlegroups.com.
>> Para anular tu suscripción a este grupo, envía un correo electrónico a

>> altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsu...@googlegroups.com>


>> Para tener acceso a más opciones, visita el grupo en
>> http://groups.google.com/group/altnet-hispano?hl=es.
>>
>
> --
> Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de
> Grupos de Google.
> Para publicar una entrada en este grupo, envía un correo electrónico a
> altnet-...@googlegroups.com.
> Para anular tu suscripción a este grupo, envía un correo electrónico a
> altnet-hispan...@googlegroups.com
> Para tener acceso a más opciones, visita el grupo en
> http://groups.google.com/group/altnet-hispano?hl=es.
>
>

--
Enviado desde mi dispositivo móvil

Edgar Ramos

no leída,
27 oct 2010, 19:59:1027/10/10
a altnet-...@googlegroups.com
José

Entonces Caliburn, es posible utilizarlo directamente en WinForm ?

Busco entre muchas cosas lo siguiente

.- Entender el patron MVP, con los links que me ponen y que estoy revisando este momento
.- porder hacer uso de un framework para aplicarlo en winform

Muchas gracias

Edgar

José F. Romaniello

no leída,
27 oct 2010, 21:58:0827/10/10
a altnet-...@googlegroups.com
El 27 de octubre de 2010 20:59, Edgar Ramos <eramo...@gmail.com> escribió:
José

Entonces Caliburn, es posible utilizarlo directamente en WinForm ?

bueno, hay un tipo que escribió que lo utilizaba con winforms. Yo no le veo la utilidad ahí y no te lo aconsejaría.. El link que te pase es para entender los patrones mas que nada, los frameworks van y vienen... los patrones y las teorías son bastante menos efímeras.

MVP es algo que ni el propio Martín Fowler pudo terminar de explicar bien y lo termino dividiendo en dos patrones. Uno es el llamado Passive View y el otro es el llamado Supervising Controller. 

Ambos pueden ser utilizados en Winforms.

Patrón Passive View

 hay gente escéptica al databinding de winforms y prefiere utilizar Passive View. En este patrón la implementación del View puede ser mas liviana pero su interfaz tiende a ser mas pesada (más métodos). La característica mas importante de este patrón es que el VIEW no conoce ningún modelo, ni viewmodel, ni objetos de dominio, absolutamente nada.

El Presenter tiene que hacer más llamadas al view "seteando" o configurando cada uno de los controles de presentación, un ejemplo sencillo de esto podría ser... imaginate una pantalla para editar los datos del cliente, donde al principio hay que mostrar todos los datos del cliente y cuando el usuario aprieta el boton editar ... guardarlos. Una interfaz de view podría ser algo así:

public interface IEditCustomerView
{
 void AgregarPaisAlCombo(string codigoIso, string nombrePais);
 void SetNombre(string valor);
 void SetApellido(string valor);
 void SetCuit(string valor);
 void SetPais(string codigoIso);
 //****tal vez todos estos mismos Set como Gets....

 event EventHandler GuardarClick;
 event EventHandler CancelarClick;
}

Esta interfaz es lo que tu FORM tiene que implementar.

Luego el presenter podría tener esta forma:

public class EditarClientePresenter 
{
  public EditarClientePresenter(IEditarClienteView editarClienteView, IRepositorioCliente repositorioCilente, IRepositorioPaise ...){...}

  public void Iniciar(int idCliente){
    var cliente = repositorioCliente.Get(idCliente);
    //obtener todos los paises recorrer uno por uno y llamar al view.AddCliente
    editarClienteView.SetNombre(cliente.Nombre)..

   editarClienteView.GuardarClick += GuardarCliente;
  }

   private void GuardarCliente(object sender, EventArgs args)
   {
     //obtener cliente, y para cada propiedad hacer cliente.Nombre = editarClietneView.GetNombre();
   }
}

Patrón supervising controller

Este patrón aprovecha una infrastructura de databinding simple. La implementación del View puede ser un poco mas compleja, aunque en winforms no lo es ya que el databinding de winforms nos ayuda en este punto, la interfaz del view es mucho más sencilla y la implementación del presentar puede ser más sencilla también. En este patrón el view si conoce los modelos que nosotros queramos que conozca. Algunas personas pueden decir que en este patrón el View solo debería conocer de ViewModels o DTOs, otra visión más prágmatica es usar ViewModel y DTO cuando corresponda y tener la libertad de usar Objetos de dominio cuando uno lo desee. 

Básicamente para el mismo caso de uso la interfaz del View podría ser así:

public interface IEditarClienteView
   ClienteViewModel ClienteEnEdicion {get;set;}
   IEnumerable<PaisViewModel> PaisesParaSeleccion {get;set;}
   event EventHandler GuardarClick;
}

el presenter sería algo así:

public class EditarClientePresenter
{
  public EditarClientePresenter(IEditarClienteView editarClienteView, IRepositorioClientes, IRepositorioPaises){...}

  public void Iniciar(int clienteId){
     editarClienteView.PaisesParaSeleccion = repositorioPais.OBtenerTodosOrdenadosPorNombre() .... Mapeo Objeto- ViewModel..
     editarClienteView.ClienteEnEdicion = repositorioCliente.Get(clietneId)..... MAPEO OBJETO - VIEWMODEL. Puede ser manual o automapper.
    editarClienteView.GuardarClick += GuardarClicked...  
  } 
 private void GuardarClicked(....)
 {
   var cliente = ... obetner el cliente con el id..
   //mapear las propiedades del vm (editarClienteView.ClienteEnEdicion ) al objeto de dominio 
   //guardar
 }
}

El form se arma con el designer, agregando un databinding... del tipo de objeto, apuntandolo a ClienteviewModel, luego con el mismo designer de datasources podes arrastrar cada control al formulario. En el formulario te van a quedar unos controles "clienteViewModelBindingSource1" algo así... En el código behind del form te quedaría basicamente algo así

public class FormEditarClienteView : Form... , IEditarClienteView
{
  public ClienteViewModel ClienteEnEdicion 
  { 
   get{ return (ClienteViewModel)clienteViewModelBindingSource1.DataSource;}
   set{ clienteViewModelBindingSource.DataSource = value}
  }
  
  public IEnumerable<PaisViewModel> Paises
 {
  get{return (IEnumerable<PaisViewModel>)paisViewModelBindingSource1.DataSource;
  set{  paisViewModelBindingSource1.DataSource = value }
  }

  public event EventHandler GuardarClick
  { 
    add{ botonGuardar.Click += value; }
    remove{botonGuardar.Click -= value; }
  }
}


Notas en general

Esta es mi interpretación de ambos patrones, puede ser que yo haya interpretado muy mal, decírmelo!

Siempre es importante recordar como uno llega a necesitar hacer esto, nunca hay que perder de vista la meta. Uno hace esto para separar las responsabilidades y de esa forma tener un código más limpio y fácil de testear. En general una pantalla es difícil de testear y todos estos patrones MVC, MVVM, MVP Passive View y Supervising controller nacieron por esa razón, por la razón de que testear la pantalla es difícil.  Con cualquiera de los dos patrones que explique aca el presenter es muy sencillo de probar, y el view es muy sencillo de crear un mock o un stub. Lo mismo con el repositorio que use de ejemplo, aunque esta es solo una alternativa podría ser que ese repositorio fuera un webservice o cualquier otra cosa.



Fin

Perdón que me haya copado escribiendo, esto hubiera ido mejor seguramente en un blog... pero me salió así. Si alguien tiene ganas de ponerlo en un post o en algún otro lugar bienvenido sea! 

Edgar Ramos

no leída,
27 oct 2010, 22:34:5527/10/10
a altnet-...@googlegroups.com
Muy agradecido José, me econtraba leyendo  supervising controller de la url que me enviaron, y me estaba costando un poco
entenderlo, hoy me queda mas claro, no esta si no, ponerlo en practica y empezar a testear

Muy gentil

Sigo leyendo y aprendiendo

Walter Poch

no leída,
27 oct 2010, 23:38:2827/10/10
a altnet-...@googlegroups.com
Excelente José, yo interpreto lo mismo que vos... así que de no ser así somos dos los equivocados.

Para mi merece que lo publiques en tu blog, es de las explicaciones más sencillas que leí de MVP.

Abrazo,

--
Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a altnet-...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a altnet-hispan...@googlegroups.com
Para tener acceso a más opciones, visita el grupo en http://groups.google.com/group/altnet-hispano?hl=es.



--
Saludos,

Walter G. Poch
Sr. .Net Developer
--------------------------------------------
Cell: +54 (9 341) 3353273
walte...@gmail.com

Jose Fabricio Rojas

no leída,
28 oct 2010, 6:31:5728/10/10
a altnet-...@googlegroups.com
+1 , Esta bueno , merece post!

José F. Romaniello

no leída,
28 oct 2010, 12:33:1228/10/10
a altnet-...@googlegroups.com
Acabo de escribir un post de Passive View con el ejemplo de todo el código que comente corriendo:

Durante los próximos días voy a hacer lo mismo para Supervising Controller y hasta  MVVM :P sobre el mismo ejemplo sencillo.

saludos!

Edgar Ramos

no leída,
28 oct 2010, 13:37:5228/10/10
a altnet-...@googlegroups.com
Si hay algun comentario, te lo dejamos en tu blog, o lo exponemos aqui ?

Saludos

Edgar

José F. Romaniello

no leída,
28 oct 2010, 14:29:2928/10/10
a altnet-...@googlegroups.com
donde vos quieras amigo

Edgar Ramos

no leída,
28 oct 2010, 14:36:1928/10/10
a altnet-...@googlegroups.com
Acabo de descargarme el ejemplo, y en mi caso personal, que siempre desarrolle sin seguir un patron, es como que, durante todo este tiempo he ido por el camino de las sombras, hasta llegar aqui.

En hora buena, el ejemplo es sencillo y facil de entender, voy a la espera de supervising controller

Saludos

Edgar

Edgar Ramos

no leída,
28 oct 2010, 14:37:3728/10/10
a altnet-...@googlegroups.com
Por cierto estos temas podrían discutirse en una VAN /AlNet Cafe cierto ?

Saludos

Edgar Ramos

no leída,
28 oct 2010, 14:45:4828/10/10
a altnet-...@googlegroups.com
Aqui mi duda

Tengo un caso de uso en el que posiblemente utilice mas de un formulario

.- un formulario implementa una y solo una interfaz de la view verdad ?
.- ahora el presenter, debera ser solo uno para gestionar todas mis views de este caso de uso ?

Muchas gracias por los comentarios

José F. Romaniello

no leída,
28 oct 2010, 14:57:2828/10/10
a altnet-...@googlegroups.com
Por lo general, 1 view - 1 presenter.
Comunicación entre presenters es todo un tema que discutíamos hace un momento por twitter con Walter Poch y Eber Irigoyen.

En algunos casos conviene utilizar algo como mi event agregator http://jfromaniello.blogspot.com/2010/04/event-aggregator-with-reactive.html (o el de prism), la teoría de este patrón esta en Martin Fowler; http://martinfowler.com/eaaDev/EventAggregator.html .

En otros caso tal vez inyectar una interfaz del presenter en otro presenter... 

En otros casos conviene utilizar el patrón ScreenConductor-Subject; este patrón se utiliza en interfaces de usuario MDI o TDI, cuando por ejemplo no podes estar editando el mismo cliente en dos tabs separados... Entonces el subject es algo así:

public class EditarClienteSubject
{
   public int IdCliente{get;set;}
  /definir equality members basados en IdCliente
}

El "Conductor" sabe que no puede haber dos pantallas con mismo subject, y en caso de que vos le pidas que abra una que ya tiene abierta, en lugar de abrir le va a dar foco.

Esa es otra forma de comunicación entre presenters, ya que el subject posee ademas los datos de inicialización para el segundo presenter. Este patrón esta muy bien definido en la wiki de Jeremy D Miller y esta implementando en caliburn (para wpf).

José F. Romaniello

no leída,
3 nov 2010, 10:28:383/11/10
a altnet-...@googlegroups.com

Edgar Ramos

no leída,
3 nov 2010, 20:15:203/11/10
a altnet-...@googlegroups.com
José

Con respecto al binding de supervising controller, y de hacerlo directamente sobre tu dominio

.- Si mi caso de uso es mas complejo (un conjunto de clases) sería  conveniente crear un viewmodel+automapper ?, recordaba que Cristian opinaba en otro hilo, pero sobre asp net mvc, de no exponer mi modelo directamente 


Saludos

Edgar

José F. Romaniello

no leída,
4 nov 2010, 10:18:184/11/10
a altnet-...@googlegroups.com
si, hay otras razones por las cuales no podrías usar directamente la entidad.... Si uno quiere ser más consistente sería una.
Otra sería cuando en el client side no tenes, y no podes tener entidades, es decir cuando hay una separación física de capas...

Edgar Ramos

no leída,
4 nov 2010, 10:27:224/11/10
a altnet-...@googlegroups.com
Gracias José, por curiosidad tu sigues desarrollando en WinForm para escritorio ?


Saludos

Edgar

Walter Poch

no leída,
4 nov 2010, 10:27:344/11/10
a altnet-...@googlegroups.com
Yo en este caso también me gustaría mencionar algo que veo muy seguido en los ejemplos MVC,

Producto/Edit/1

Para demos eso esta bien, pero en el mundo real es un security flaw muy grande. Para mi las entidades deberían quedar del Controller para atrás a la Vista un ViewModel o Dto.

Por ejemplo:

public class Producto {
   public virtual int Id {get; protected set;}
   public virtual string Nombre {get; set;}
}

public class ProductoDto{
  public string Id {get;set;}
  public string Nombre {get;set;}
}

Donde el Id del ProductoDto iría encriptado.

Producto/Edit/SDFSDAGDFGDSAFGDSFGSDFGDSF

Mi granito de arena,

Saludos,

Mario Cornejo

no leída,
4 nov 2010, 10:40:304/11/10
a altnet-...@googlegroups.com
No lo veo como un security flaw mostrar el ID. El ID del producto no tiene que ser necesariamente un secreto (podrías usar el código de barras en lugar del ID por ejemplo, el cual esta visible en el mismo producto). Un security flaw seria editarlo sin revisar que el usuario tenga realmente permiso para hacerlo.

mis 2 centavos

Mario Cornejo

2010/11/4 Walter Poch <walte...@gmail.com>

José F. Romaniello

no leída,
4 nov 2010, 10:45:174/11/10
a altnet-...@googlegroups.com
Yo mas o menos estoy de acuerdo con Mario.. no entiendo que podría hacer un usuario mal intencionado con nuestro id de producto.. Ademas yo uso casi siempre una técnica de POID y ese ID ni si quiera tiene significado en el dominio.

Walter Poch

no leída,
4 nov 2010, 11:12:454/11/10
a altnet-...@googlegroups.com
Mario:
Si mostras el código de barra estaría bien, yo no quiero mostrar algo que mi sistema usa internamente para referenciar el objeto y generar relaciones.

Entiendo que la falla estaría en validar los permisos, pero muchas veces pasa que no se validan, y no digo en la pantalla de edición, pero tal vez en la que muestra los datos, o en una búsqueda por AJAX que llena un combo, etc.. donde pasas el ID, y no haces el chequeo de permisos que corresponde y pum... alguien accede a información a la que no debería.

Usando un POID diferente es menos probable que lo "adivinen" pero existe la posibilidad. Yo usaría GUID, pero me mantengo con HiLo, por el tema de legibilidad humana, y fragmentación.

Es más que nada para ejemplificar porque a veces el Entity como viene no lo uso en la vista... Y sigo sin preferir pasar información de mi funcionamiento interno al público general, donde los ID son privados del funcionamiento del sistema, y los usuarios finales no debería porque conocerlos. No son del "negocio".

Saludos,
Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos