開発中のAndroidアプリでMVPパターンを使用しています。
基本的に4つの要素があります。
私の質問は:
AddUserViewの[追加]ボタンを押すと、テキストビューのコンテンツが取得され、新しいUserInfoがインスタンス化されて、Presenterに渡されます。または、AddUserViewは単にtextViewsコンテンツを取得してAddUserPresenterに渡す必要があります。これにより、実際にはUserInfoがインスタンス化され、UserInfoManagerに渡されますか?
マーティンファウラーのMVPの説明によると( http://martinfowler.com/eaaDev/uiArchs.html )
MVCのビュー部分のうち、Fowler氏は次のように述べています。
Potelの最初の要素は、ビューをウィジェットの構造、フォームとコントロールモデルのコントロールに対応するウィジェットとして扱い、ビューとコントローラーの分離を削除することです。 MVPのビューは、これらのウィジェットの構造です。ウィジェットがユーザーの操作にどのように反応するかを示す動作は含まれていません。
(太字強調鉱山)
その後、プレゼンターの:
ユーザーの行動に対するアクティブな反応は、別のプレゼンターオブジェクトにあります。ユーザージェスチャーの基本的なハンドラーはウィジェットにまだ存在しますが、これらのハンドラーは単にプレゼンターに制御を渡します。
プレゼンターは、イベントへの対応方法を決定します。Potelは、主にモデルのアクションに関してこの相互作用について説明します。これは、コマンドのシステムによって行われます。と選択。ここで強調すべき便利な点は、モデルへのすべての編集をコマンドにパッケージ化するアプローチです。これは、元に戻す/やり直し動作を提供するための優れた基盤を提供します。
(再び、大胆な強調鉱山)
したがって、Fowlerのガイドラインに従って、ビューはボタンイベントに応答する動作に対して責任を負うべきではありません。これには、UserInfo
のインスタンスの作成が含まれます。オブジェクトの作成を決定する責任は、UIイベントの転送先のPresenterメソッドにあります。
ただし、ビューはボタンイベントをforwardingするだけなので、textView
のコンテンツを渡す責任もビューのボタンイベントハンドラーにもないことを主張することもできます。プレゼンターとそれ以上。
MVPでは、プレゼンターがビューから直接データを取得するために使用できるインターフェイスをビューが実装するのが一般的です(プレゼンターがビュー自体にまだ無知であることを確認しながら)。 UserInfoは単純なPOJOであるため、ビューがUserInfoのgetterを公開して、プレゼンターがインターフェイスを介してビューから取得できることは有効な場合があります。
_// 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
をビューに直接渡すこととどう違うのですか?主な違いは、プレゼンターがlogicを最終的に担当し、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
ステートメントであっても、空のテキストボックスをチェックするか、チェックボックスのブール値である場合)、それはプレゼンターに属します。