Mostrando una vista desde otra vista en MVP

7

Esta pregunta es sobre triadas de MVP. Digamos que tengo dos tríadas y la primera tiene View1 , Mode1 y Presenter1 . La segunda tríada tiene View2 , Model2 y Presenter2 . Ahora, lo que intento hacer es simplemente mostrar el View2 cuando hago clic en button en View1 .

Deberías mostrar el View1 llamando al método show del presentador.

View1Presenter presenter1 = new View1Presenter (view1, Model1);
presenter1.show();

Ahora cuando hago clic en el botón btnShowView2 en el View1 , debería mostrar el View2 .

Entonces, ¿cómo llamar a presenter2.show() desde View1 ?

    
pregunta CAD 16.06.2014 - 06:13

1 respuesta

5

Mostrar una segunda vista en btnShowView2.Clicked es algún tipo de lógica de negocios, por lo que el lugar correcto para implementar esto es en el controlador de eventos de presenter1 que se ocupa de ese evento (supongo que presenter1 está registrado en todos los botones relevantes -Haga clic en eventos de View1 ). Llamémoslo HandleBtnView2Click , por lo que el código inicial dentro de ese controlador podría tener este aspecto:

  void HandleBtnView2Clicked(object sender, EventArgs e))
  {
       IView2 view2 = new View2();
       Model2 model2 = model1.GetRefToModel2(); // or whatever is needed to get model2
       View2Presenter presenter2 =new View2Presenter(view2,model2);
       presenter2.show();
  }

Pero en realidad, esta no es una buena solución, ya que implicaría que la capa presenter2 debe estar vinculada a la biblioteca de UI (en su caso, WinForms), que en el peor de los casos evita las pruebas automáticas.

La mejor solución es delegar la creación de View2 en una tercera instancia, que se puede burlar fácilmente. En general, es posible utilizar una fábrica abstracta para esto. En el caso específico, también es posible usar View1 para la creación de View2 . Agrega un método a tu interfaz IView1 :

 interface IView1
 {
    // ...
      IView2 CreateView2();
 }

y utilícelo en el código anterior:

  void HandleBtnView2Clicked(object sender, EventArgs e))
  {
       IView2 view2 = view1.CreateView2(); // view1 is of type IView1 and a member of presenter1
       Model2 model2 = model1.GetRefToModel2(); // or whatever is needed to get model2
       View2Presenter presenter2 =new View2Presenter(view2,model2);
       presenter2.show();
  }

Ahora, cuando desee probar automáticamente su presenter1 , provéale una implementación simulada de view1 que implemente el método CreateView2 de una manera que devuelva una simulación de view2. En la clase View1 , implementas CreateView2() para devolver el new View2() , por lo que la responsabilidad de crear vistas permanece en la capa de la vista.

Si lo desea, puede ir un paso más allá y hacer que presenter1 sea comprobable en forma aislada de presenter2 . Si cree que es necesario, cree una interfaz IPresenter2 y coloque todo el código de creación anterior en un resumen "presenter factory":

   void HandleBtnView2Clicked(object sender, EventArgs e))
   {
        IPresenter presenter2 = presenterFactory.CreatePresenter2(model1);
        presenter2.show();
   }

El presenterFactory debe inyectarse en su presentador1 en el momento de la construcción y puede ser reemplazado por un simulacro en su conjunto de pruebas. Si es necesario, tienes que decidir por ti mismo. Agregará una capa adicional de complejidad a su código para el beneficio de una mejor capacidad de prueba.

    
respondido por el Doc Brown 16.06.2014 - 09:46

Lea otras preguntas en las etiquetas