web-dev-qa-db-ja.com

さまざまなワークフローで再利用できるように、アクティビティナビゲーションロジックを汎用的に保つ方法

私は構造化しますAndroid Uncle Bobのアプリケーションに従いますClean Architectureこれは基本的に少なくとも以下の関連するレイヤーで構成されます:-

  • プレゼンテーション-MVVMアプローチを使用。このレイヤーには、Androidのアクティビティとそれに対応するViewModelが含まれています。
  • Interactor-このレイヤーは、アプリケーションのユースケースロジックをカプセル化し、基本的にはビジネス固有のタスクを達成するために複数のViewModelから呼び出されます。タスクの進捗状況を反映した状態を維持することもできます。

現在、私のアプリケーションには少数のユースケースまたはワークフローがあります。各ワークフローは、特定の一連のページ(つまり、アクティビティまたはフラグメント)を通過します。ページとワークフローが少ないので、ナビゲーションロジックを各ViewModel内に明示的に配置することは単に意味があります。次のアクティビティを通過するユースケースAがあるとします。

ユースケースA _[HomeActivity] --> [ActivityA] --> [ActivityB]_

ActivityAActivityBの対象となる選択項目のリストをユーザーに提示すると想像してください。 ActivityAでは、単に呼び出すだけです

startActivity(new Intent(this, ActivityB.class))

ユーザーがアイテムの選択を完了し、インタラクターを既に呼び出して、ユーザーが選択しているアイテムの状態を保持しているときに、ActivityBに移動します。

...

これで問題が発生し、ビジネスには新しいワークフローが必要になりますユースケースBが必要ですが、ワークフローでは同じActivityAが再利用されます。

ユースケースB _[HomeActivity] --> [ActivityA] --> [ActivityC]_

ご覧のとおり、ActivityAは、ActivityBだけでなくActivityCにも移動できます。これは、どのユースケースに参加しているかによって異なります。ActivityAのロジックのほとんどと、そのビューXMLおよびそのViewModelは、両方のユースケースで再利用できるほど汎用的ですが、ナビゲーション部分はそうではありません。

このナビゲーションの問題にどのように対処すれば、ActivityAとその関連要素のコードが、ワークフローで再利用できるように汎用的になりますか?あなたのアイデアから最もエレガントなソリューションは何ですか?

3
onelaview

私があなたを正しく理解している場合、activityAを開始する前に、activityAの後に移動するアクティビティを選択していますか?

私が考えることができる最も簡単な解決策は、activityAから継承し、goToNextActivity()のようなメソッドをオーバーライドすることです。ただし、これは将来的には少し理解しにくくなる可能性があります。もう1つは、「ワークフロー」の概念を明確にすることです。あなたはそれらに名前を付けて、それを追加としてアクティビティに与えることができます。その後、アクティビティはNavigation.goToNextScreen(this、workflow)のような場所でユーティリティメソッドを呼び出すことができます。次に、ナビゲーションメソッドは、各ワークフローの各アクティビティの後に移動する場所を決定し、ワークフローを含むエクストラを設定することもできます。

1
Hendrik Marx

私の意見では、「ワークフロー」はビジネスロジックの一部であるか、ビジネスレイヤー(「サービスレイヤー」)の上にあるレイヤーです。

ViewModellはGUIとの通信を担当します。

食品やタバコを販売するオンラインショップがあるとします。

ワークフローロジックにはブール関数customerMustBeOlderThan18Years()を含めることができます

ショッピングカートにシガレットが存在する場合、viewModelには、「ProveThatCustomerIsOlderThan18YearsActivity」にインテントを返すメソッドgetActivityIntentForNextCommand()があります。

1
k3b

複数の使用可能なアプローチが見られます。

最初のものは、あなたのActivityBValue Picker Controlとして識別し、それを1つのように扱うことです。これは汎用である必要があるため、すべての動作は外部から構成可能である必要があります。

easierこの方法を別の場所で再利用できるようにする方法は、@ Hendrik Marxがすでに提案しているように、継承によって継承します。

だからあなたは抽象的なBaseActivityBと、ナビゲーションを開始するときに呼び出すメソッドをオーバーライドする2つの実装を持っています。

2番目のより複雑なオプションは、ActivityBにバンドルパラメータをonCreateから読み取らせ、後でこれらのパラメータに基づいて決定することです。

さまざまな使用法を非常に明確にするため、継承アプローチを強くお勧めします。また、Intentにバンドルされているパラメーターを使用する場合は、多くの異なるナビゲーションロジックを1つのクラスに配置することを意味します(単一責任の原則と考えてください)。

1
Kai Brummund