シナリオの例は次のとおりです:
アクティビティ(ビュー)とそのビューのプレゼンターがいます。プレゼンターは、ネットワークAPIからユーザーのリストをフェッチし、Listオブジェクトを使用してそれをメモリに保持します。アクティビティには、User.typeに基づいてユーザーに関するコンテンツを表示するためのさまざまなタイプのフラグメントが含まれています。 2つのフラグメント(UserType1FragmentとUserType2Fragment)にも、それぞれ独自のプレゼンターがあります。
アクティビティのプレゼンターは、次に表示されるフラグメントのタイプ(IまたはII)を決定します。フラグメントのプレゼンターは、ユーザーオブジェクトの表示方法を決定し、killUser()と呼ばれるボタンクリックイベントを処理します。これにより、アクティビティのプレゼンターのListオブジェクトが更新されます。
ここに問題があります:
フラグメントプレゼンツは、アクティビティプレゼンターのデータをどのように参照していますか?プレゼンターは互いに直接コミュニケーションをとるべきではありません。たぶん私はリストをリポジトリ/インタラクターに抽象化する必要がありますか?リストはプレゼンター間でどのように共有されますか?
そのため、@ Jahnoldが推奨するようなものを実装することになりました。 (私はアイデアのために提供されたリンクに図を投稿します stackoverflow.com/a/41966497/568898 )
Hannes Dorfmann(有名なMosby MVPライブラリを作成/管理した人: Githubリンク )も私をこの方向に向けました。
実装
メインアクティビティのプレゼンターと、そのアクティビティで使用できる複数のフラグメントがあります。各フラグメントには独自のプレゼンターがあります。次に、基本的にモデルとビジネスロジックを格納するリポジトリ(リポジトリパターンの検索)を使用します。私のユースケースでは、このリポジトリをシングルトンとして保持します。リポジトリは、オンラインAPI、sqlliteデータベース、またはメモリに保存されたキャッシュ(基本的にはアイテムの配列リスト)からの3つの形式でデータを提供します。また、このリポジトリには、現在の状態に基づいて更新されるcurrentitemintインデックスなどがいくつかあります。
したがって、データ、状態、およびビジネスロジックは、この共有リポジトリに格納されます。プレゼンターと意見はかなり馬鹿げています。プレゼンターにはビジネスロジック(アプリケーション固有のロジック)があまりありません。それらは、データの表示方法(特定のロジックを表示)に関連付けられたロジックと、それらのロジックでの前処理を持っているだけです。
例
ユーザーが子フラグメントのボタンをクリックしたときにフラグメントとアクティビティが(プレゼンターを介して)相互に通信する必要がある場合は常に、フラグメントはプレゼンターにhandleClickを要求し、プレゼンターはリポジトリのcurrentItemSelectedデータ(または他の何か)を更新してフラグメントに要求しますアクティビティが実装するインターフェイスリスナーにイベント(onbuttonclickなど)を発生させます。アクティビティがイベントを取得すると、それを処理するように自身のプレゼンターに要求し、次にアクティビティプレゼンターは、新しいcurrentItemSelectedを取得するためにリポジトリ内の更新を探します。
追加情報(詳細バージョン):
また、MVPアーキテクチャのより高度なバージョンの一種であるクリーンアーキテクチャに従うこともできます。 MVPはビューのアーキテクチャのみを扱いますが、クリーンアーキテクチャはビジネスロジックとデータアーキテクチャも扱いますが、MVPはビューの処理に使用されるクリーンなArchのほんの一部です。これを使用すると、私の場合のメガリポジトリを、特定のビジネスロジックのユースケースを処理するさらに別のユースケース(またはインタラクター)に分割でき、リポジトリはデータを提供するだけです。したがって、ロジックフローはビュー->プレゼンター->インタラクター->レポになります。
フラグメントのnewInstance()を介して、フラグメントへのリスト参照を渡すことができます。プレゼンター同士が直接コミュニケーションをとるべきではないと思います。