この質問は、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()
を呼び出す方法は?
_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に挿入する必要があり、テストスイートのモックに置き換えることができます。それが必要な場合は、自分で決める必要があります。テスト性を向上させるために、コードにさらに複雑なレイヤーを追加します。