web-dev-qa-db-ja.com

MVPで別のビューのビューを表示する

この質問は、MVPトライアドに関するものです。 2つのトライアドがあり、最初のトライアドには_View1_、_Mode1_および_Presenter1_があるとします。 2番目のトライアドには、_View2_、_Model2_、および_Presenter2_があります。ここでやろうとしていることは、_View2_のbuttonをクリックしたときに_View1_を表示することだけです。

プレゼンターのshowメソッドを呼び出す_View1_を表示します。

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

_btnShowView2_の_View1_ボタンをクリックすると、_View2_が表示されます。

では、_View1_からpresenter2.show()を呼び出す方法は?

7
CAD

_btnShowView2.Clicked_に2番目のビューを表示することは、ある種のビジネスロジックであるため、これを実装する適切な場所は、そのイベントを処理する_presenter1_のイベントハンドラー内です(presenter1はすべての関連するものに登録されていると想定しています) _View1_のボタンクリックイベント)。それを_HandleBtnView2Click_と呼ぶと、ハンドラー内の初期コードは次のようになります。

_  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();
  }
_

しかし、実際には、これは適切な解決策ではありません。これは、presenter2レイヤーをUIライブラリ(あなたの場合はWinForms)にリンクする必要があることを意味し、最悪の場合、自動テストが妨げられます。

より良い解決策は、_View2_の作成を3番目のインスタンスに委任することです。一般に、これには抽象ファクトリを使用できます。特定のケースでは、_View1_の作成に_View2_を使用することもできます。 _IView1_インターフェイスにメソッドを追加します。

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

上記のコードで使用します。

_  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();
  }
_

_presenter1_を自動的にテストする場合は、view2のモックを返すように_CreateView2_メソッドを実装するview1のモック実装を提供します。 _View1_クラスでは、CreateView2()を実装してnew View2()を返すため、ビューを作成する責任はビューレイヤーにあります。

必要に応じてさらに一歩進んで、_presenter1_から分離して_presenter2_をテスト可能にすることができます。それが必要だと思う場合は、インターフェイス_IPresenter2_を作成し、上記の作成コード全体を抽象的な「プレゼンターファクトリ」に入れます。

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

presenterFactoryは、構築時にプレゼンター1に挿入する必要があり、テストスイートのモックに置き換えることができます。それが必要な場合は、自分で決める必要があります。テスト性を向上させるために、コードにさらに複雑なレイヤーを追加します。

6
Doc Brown