用于不同 Rx 源的通用 RxJava2 转换器

iam*_*mal 5 java android abstraction interface rx-java

我意识到这可能属于库设计和功能实现的范围,但想问问我们是否可以在不同来源(例如 Observable 和 Completable)上使用 Transformer,因为它们共享很多方法,特别是侧面效果。我们没有通过扩展来创建我们自己的操作符,而是创建了转换器来处理我们通常与可观察对象和可完成对象一起使用的逻辑。

例如,我们没有包装 subscribe 调用返回的一次性对象,而是为它创建了一个 Transformer 函数:

public static <T> ObservableTransformer<T, T> dispose(CompositeDisposable compositeDisposable) {
    return observable -> observable.doOnSubscribe(compositeDisposable::add);
}
Run Code Online (Sandbox Code Playgroud)

现在,这不适用于 Observable 以外的任何其他来源,我们需要添加另一种方法来完成

public static CompletableTransformer disposeCompletable(CompositeDisposable compositeDisposable) {
    return completable -> completable.doOnSubscribe(compositeDisposable::add);
}
Run Code Online (Sandbox Code Playgroud)

这已经成为一种模式,只处理 2 个具有完全相同方法的不同源的转换器

例如

public static <T, V extends Progressive & Erroneous> ObservableTransformer<T, T> progressiveErroneous(V view) {
    return observable -> observable
        .compose(progressive(view))
        .compose(erroneous(view));
}

public static <V extends Progressive & Erroneous> CompletableTransformer progressiveErroneousCompletable(V view) {
    return observable -> observable
        .compose(progressiveCompletable(view))
        .compose(erroneousCompletable(view));
}
Run Code Online (Sandbox Code Playgroud)

对于这些,我们必须实现progressiveCompletable(view)erroneousCompletable(view),方法体没有区别。

我们还想从我们的控制器中删除测试,只测试这些转换器在视图接口上调用正确的方法。这将大大减少冗余测试,这就是我们选择这种抽象设计的原因。但是如果我们继续重复这样的方法,测试将非常重复。如果我们开始使用其他来源,例如 Flowable、Maybe 等,情况只会变得更糟

有什么方法可以使用抽象转换器,这些转换器在支持常见操作的源范围上运行,例如

  • 订阅
  • 执行错误
  • 最后做
  • 等等