マーティンファウラーによるMVPの説明(http://martinfowler.com/eaaDev/uiArchs.html)によると
MVCのビュー部分のうち、Fowler氏は次のように述べています。
Potelの最初の要素は、ビューをウィジェットの構造、フォームとコントロールモデルのコントロールに対応するウィジェットとして扱い、ビューとコントローラーの分離を削除することです。MVPのビューは、これらのウィジェットの構造です。ウィジェットがユーザーの操作にどのように反応するかを表す動作は含まれていません。
(太字強調鉱山)
その後、プレゼンターの:
ユーザーの行動に対するアクティブな反応は、別のプレゼンターオブジェクトにあります。ユーザージェスチャーの基本的なハンドラーはウィジェットにまだ存在しますが、これらのハンドラーは単にコントロールをプレゼンターに渡します。
プレゼンターは、イベントへの対応方法を決定します。Potelは、この相互作用を主にモデルのアクションの観点から説明します。これは、コマンドと選択のシステムによって行われます。ここで強調すべき便利な点は、モデルへのすべての編集をコマンドでパッケージ化するアプローチです。これは、元に戻す/やり直し動作を提供するための優れた基盤を提供します。
(再び、大胆な強調鉱山)
したがって、Fowlerのガイドラインに従って、ビューはボタンイベントに応答する動作に対して責任を負うべきではありません。これには、のインスタンスの作成が含まれますUserInfo
。オブジェクトの作成を決定する責任は、UIイベントの転送先のPresenterメソッドにあります。
ただし、textView
ビューはボタンイベントを単にPresenterに転送するだけなので、ビューのボタンイベントハンドラーもコンテンツの受け渡しに責任を負うべきではないと主張することもできます。
MVPでは、プレゼンターがビューから直接データを取得するために使用できるインターフェイスをビューが実装するのが一般的です(プレゼンターがビュー自体を認識していないことを確認しながら)。UserInfoは単純なPOJOであるため、プレゼンターがインターフェイスを介してビューから取得できるUserInfoのゲッターをビューが公開することは有効な場合があります。
// The view would implement IView
public interface IView {
public UserInfo GetUserInfo();
}
// Presenter
public class AddUserPresenter {
private IView addUserView;
public void SetView(IView view) {
addUserView = view
}
public void onSomethingClicked() {
UserInfo userInfo = addUserView.GetUserInfo();
// etc.
}
}
これはUserInfo
、イベントハンドラーを使用して直接ビューに渡すのとどう違うのですか?主な違いは、プレゼンターはオブジェクトを作成するロジックを最終的に担当UserInfo
することです。つまり、イベントはの作成前にプレゼンターに到達し、プレゼンターUserInfo
が決定できるようにしました。
UserInfo
ビュー内のある状態に基づいて作成したくないプレゼンターロジックがあるシナリオを想像してみてください。たとえば、ユーザーがビューのチェックボックスをオンにしていない場合、またはUserInfoに追加する必要のあるフィールドに対する検証チェックが失敗した場合-プレゼンターは、呼び出す前に追加のチェックを含む可能性がありますGetUserInfo
-すなわち
private boolean IsUsernameValid() {
String username = addUserView.GetUsername();
return (username != null && !username.isEmpty());
}
public void onSomethingClicked() {
if (IsUsernameValid()) {
UserInfo userInfo = addUserView.GetUserInfo();
// etc.
}
}
そのロジックはプレゼンター内に残り、ビューに追加する必要はありません。ビューが呼び出しを担当する場合、ビューのGetUserInfo()
使用を取り巻くロジックも担当します。これは、MVPパターンが回避しようとしていることです。
したがって、作成するメソッドUserInfo
は物理的にViewクラスに存在する可能性がありますが、Viewクラスから呼び出されることはなく、Presenterからのみ呼び出されます。
もちろん、作成時UserInfo
にユーザー入力ウィジェットのコンテンツ(文字列変換、検証など)に対する追加のチェックが必要になる場合は、検証/文字列変換にかかるように、これらの個別のゲッターを公開することをお勧めします。プレゼンター内に配置し、プレゼンターがを作成しますUserInfo
。
全体として、Presenter / Viewの分離に関する主な目標は、ビューにロジックを記述する必要がないことを保証することです。if
何らかの理由でステートメントを追加する必要がある場合(if
ウィジェットプロパティの状態に関するステートメントであっても-空のテキストボックスのチェック、またはチェックボックスのブール値)、それはプレゼンターに属します。
onSomethingClicked()
。そのため、ユーザーが「何か」をクリックすると、ビューが呼び出されpresenter.onSomethingClicked()
ますか?または、私のプレゼンターメソッドは、私の場合、目的のアクションとして名前を付ける必要がありaddUser()
ますか?