私は構造化しますAndroid Uncle Bobのアプリケーションに従いますClean Architectureこれは基本的に少なくとも以下の関連するレイヤーで構成されます:-
現在、私のアプリケーションには少数のユースケースまたはワークフローがあります。各ワークフローは、特定の一連のページ(つまり、アクティビティまたはフラグメント)を通過します。ページとワークフローが少ないので、ナビゲーションロジックを各ViewModel内に明示的に配置することは単に意味があります。次のアクティビティを通過するユースケースAがあるとします。
ユースケースA _[HomeActivity] --> [ActivityA] --> [ActivityB]
_
ActivityAがActivityBの対象となる選択項目のリストをユーザーに提示すると想像してください。 ActivityAでは、単に呼び出すだけです
startActivity(new Intent(this, ActivityB.class))
ユーザーがアイテムの選択を完了し、インタラクターを既に呼び出して、ユーザーが選択しているアイテムの状態を保持しているときに、ActivityBに移動します。
...
これで問題が発生し、ビジネスには新しいワークフローが必要になりますユースケースBが必要ですが、ワークフローでは同じActivityAが再利用されます。
ユースケースB _[HomeActivity] --> [ActivityA] --> [ActivityC]
_
ご覧のとおり、ActivityAは、ActivityBだけでなくActivityCにも移動できます。これは、どのユースケースに参加しているかによって異なります。ActivityAのロジックのほとんどと、そのビューXMLおよびそのViewModelは、両方のユースケースで再利用できるほど汎用的ですが、ナビゲーション部分はそうではありません。
このナビゲーションの問題にどのように対処すれば、ActivityAとその関連要素のコードが、ワークフローで再利用できるように汎用的になりますか?あなたのアイデアから最もエレガントなソリューションは何ですか?
私があなたを正しく理解している場合、activityAを開始する前に、activityAの後に移動するアクティビティを選択していますか?
私が考えることができる最も簡単な解決策は、activityAから継承し、goToNextActivity()のようなメソッドをオーバーライドすることです。ただし、これは将来的には少し理解しにくくなる可能性があります。もう1つは、「ワークフロー」の概念を明確にすることです。あなたはそれらに名前を付けて、それを追加としてアクティビティに与えることができます。その後、アクティビティはNavigation.goToNextScreen(this、workflow)のような場所でユーティリティメソッドを呼び出すことができます。次に、ナビゲーションメソッドは、各ワークフローの各アクティビティの後に移動する場所を決定し、ワークフローを含むエクストラを設定することもできます。
私の意見では、「ワークフロー」はビジネスロジックの一部であるか、ビジネスレイヤー(「サービスレイヤー」)の上にあるレイヤーです。
ViewModellはGUIとの通信を担当します。
食品やタバコを販売するオンラインショップがあるとします。
ワークフローロジックにはブール関数customerMustBeOlderThan18Years()
を含めることができます
ショッピングカートにシガレットが存在する場合、viewModelには、「ProveThatCustomerIsOlderThan18YearsActivity」にインテントを返すメソッドgetActivityIntentForNextCommand()
があります。
複数の使用可能なアプローチが見られます。
最初のものは、あなたのActivityBをValue Picker Controlとして識別し、それを1つのように扱うことです。これは汎用である必要があるため、すべての動作は外部から構成可能である必要があります。
easierこの方法を別の場所で再利用できるようにする方法は、@ Hendrik Marxがすでに提案しているように、継承によって継承します。
だからあなたは抽象的なBaseActivityB
と、ナビゲーションを開始するときに呼び出すメソッドをオーバーライドする2つの実装を持っています。
2番目のより複雑なオプションは、ActivityB
にバンドルパラメータをonCreate
から読み取らせ、後でこれらのパラメータに基づいて決定することです。
さまざまな使用法を非常に明確にするため、継承アプローチを強くお勧めします。また、Intent
にバンドルされているパラメーターを使用する場合は、多くの異なるナビゲーションロジックを1つのクラスに配置することを意味します(単一責任の原則と考えてください)。