Clean Architectureを使用してAndroidアプリを開発しています。RxJava2.xに移行しています。soapサービスにいくつかのネットワーク要求を作成する必要があるため、apiインターフェイスをドメインモジュール:
public interface SiginterApi {
Observable<User> login(String user, String password);
...
Observable<List<Campaign>> getCampaigns(List<Long> campaignIds);
}
ネットワーク要求は「Flowable
」で行う必要があることを読みました。これは「コールドオブザーバブル」であるため、バックプレッシャー管理のためです。一方、リクエストの結果が成功(応答あり)またはエラーになることはわかっているので、Flowable
またはSingle
、さらにはObservable
を使用すべきかどうかはわかりません。
さらに、次のようなデータベースアクセスがあります。
public interface UserRepository extends Repository {
Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user);
...
Observable<User> findUser(String username, String hashedPassword);
}
Completable
メソッドでFlowable
/Observable
/saveUser
を使用し、Single
メソッドでFlowable
/Observable
/findUser
を使用する必要があるかどうかわかりません。
バックプレッシャーは、ソースObservable
がSubscriber
が消費できるよりも速くアイテムを放出しているときに得られるものです。ほとんどの場合、ネットワーク要求などのcoldオブザーバブルではなく、hot observablesに懸念があります。
Completable
メソッドでObservable<Void>
の代わりにsaveUser
を使用し、リクエスト/レスポンスまたは入出力パターンに従うすべての場所でSingle
を使用する必要があると思います。 Observable
は、実際に連続したイベントストリームが必要な場合に使用する必要があります。
Backpressure は、Observable
がオペレーターまたはサブスクライバーが消費できるよりも速くアイテムを放出している場合に発生します。
Observable
は1つのアイテムのみを出力するため、Flowable
は適切な候補ではないため、バックプレッシャーは問題ではありません。
したがって、本当の問題は、Completable
にObservable
を使用するか、saveUser
にSingle
を使用するか、Observable
にfindUser
を使用するか、ここでは、APIを単純かつ明確にするために1つの結果(成功または失敗)のみが予想されるため、Completable
/Single
を明確に使用する必要があります。 APIユーザーに誤解を与える可能性のある値が出力されます。
カーディナリティは、Completable、MaybeとSingle:
Maybe<T>
は、カーディナリティが0または1のObservableです。つまり、存在するかどうかの結果を表します。Single<T>
は、常に結果、つまりカーディナリティ1を返すObservableです。Completable
は、Observable<Void>
すなわち、0のカーディナリティ。したがって、あなたの場合、この方法でリポジトリの署名を変更できます:
Completable saveUser(...);
Single<User> findUser(...);
( backpressure のFlowable
sのようなObservable
sについては言及しませんでした)。
私が理解しているように、シングルを使用する必要があります:アイテムを取得することを確信している場合、そうでなければエラーが発生します。例:GET-card /:id
たぶん:あなたはアイテムを取得するかどうかわからない場合の正しいソリューションです。例:GET-card?license-plate = xvar3
完了可能:アクションが実行されたかどうかのみを知りたい場合。例:PUTまたはDETELE
観察可能:アイテムの量がそれほど多くない場合。
流動性:取得するアイテムの量がわからない場合。
うーん...
あなたはより複雑な状況に直面している一方で、質問は簡単なものではないと思います。
例えば。 ユーザーの保存(REST)>ユーザーの保存(SQLlite)
chain Rxストリームを1つにしたい場合があります。
だからあなたは宣言する
1。
Flowable<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);
そして、次のいくつかを使用します:flatMap, contactMap, switchMap
2。
...またはクラスの責任を混乱させないために、より望ましいかもしれないと思う(多くの場所で同じコードを使用するかもしれない)
Single<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);
RestService.saveUser(...)
.toFlowable() // Transform into Flowable
.switchMap{ saveToDB() }
.subscribeBy{ ... }
.addTo( yourDisposable )
3。
ちなみに、Niceエラー処理が必要な場合に備えてCompletableを使用しないことをお勧めします。簡単にラップできますRetrofit.Response<Body>
in Single
またはFlowable
でサーバーからのコード応答を利用します