プレゼンターレイヤーからActivity
を開くと、アンチパターンになりますか?
その場合、View Layerからアプリのナビゲーションを管理する必要がありますか?
はい、それはアンチmvpパターンです。 MVPの パッシブビュー に基づいて、プレゼンターでAndroidフレームワークを扱う必要がないため、テスト容易性が失われました。
そのため、View Layerからアプリのナビゲーションを管理することをお勧めします。
class MyPresenter {
MyPresenter.View view;
void backButtonClicked() {
view.navigateToHomeScreen();
}
public interface View {
void navigateToHomeScreen();
}
}
class MyActivity extends Activity implements MyPresenter.View {
@Override
void navigateToHomeScreen() {
startActivity(...)
}
@OnClick(R.id.my_button)
void onClick() {
presenter.backButtonClicked();
}
}
また、この方法の別の利点は、アクティビティをフラグメントまたはビューに簡単に置き換えることができることです。
編集1:
Morgwai この方法は懸念と単一の責任の分離を壊すと言いましたが、どこでも単一の責任を持つことはできません。いつかあなたはそれに違反する必要があります。 MVP用のGoogleの例を次に示します。
TaskDetailPresenter
を呼び出します ShowEditTask
Activity
内で新しいTaskDetailFragment
を開く役割を果たします。
しかし、あなたは CommandPattern を使用することもできます。これはより良いアプローチです
interface NavigationCommand {
void navigate();
}
そのため、Presenterは必要なときに使用します。
accepted answer へのコメントで書いたように、ビューレイヤーからのナビゲーションの管理は、懸念の分離ルールの明確な破れだと思います。ビューには、現在のUI画面を更新するメソッドのみを含める必要があります。
この問題は、Androidプラットフォーム設計に起因します。Activity
およびFragment
クラスには、UI画面で操作するためのメソッドと、他のアクティビティを開始するインテントオブジェクトを送信するためのメソッドstartActivity
。
これを解決するためのクリーンな方法は、ナビゲーションに関連するメソッドを含むNavigator
インターフェイスを作成し、アクティビティに実装してプレゼンターにもインジェクトすることです。この方法では、少なくともプレゼンターの観点からのナビゲーションとUI操作は分離されます。しかし、アクティビティの観点からは奇妙に見えるかもしれません。今では、多くの場合、両方のインターフェイス(NavigatorとView)を実装し、参照をプレゼンターに2回渡します。このため、ビューレイヤーからナビゲーションを管理する場合は、少なくともUIを操作するためのメソッドとは別のナビゲーション用のメソッドを保持します。同じメソッドでナビゲーションとUI操作を実行しないでください。
私の意見では、ビューレイヤーからアクティビティを開くとよいでしょう。プレゼンターはアクティビティについてできるだけ少ししか知らないことを好みます。
どのアクティビティを開始すべきかの条件がある場合、次のようなものを使用できます。
public class Presenter {
private ViewsPresentation mViewsPresentation;
public void someButtonClicked() {
if (/*some condition*/) {
mViewsPresentation.startFirstActivity();
} else {
mViewsPresentation.startSecondActivity();
}
}
public interface ViewsPresentation {
void startFirstActivity();
void startSecondActivity();
}
}