2016-10-03 12 views
3

RxJavaを初めて使用しました。設定可能なObservableをどのように作成できるのでしょうか?のは、私はこのようなDB-へ-DB転送を書くことができます想像してみましょう:Rx-Java:設定可能なObservableを作成する

srcDb.getObservable(Bean.class) 
    .sql(selectSql) 
    .params(selectParams) 
    .subscribe(
      trgDb.getSubscriber(Bean.class) 
       .sql(insertSql) 
    ); 

私はすでに加入していることを行うことができますが、どのように私は、観察可能な自体に同じ方法でいくつかの小さなコンフィギュレーションを得ることができますか?

+0

コアRx APIに独自のメソッドを簡単に追加することはできませんが、できることは同じ種類の流暢な記述スタイルで独自のビルダーを作成し、最後に観察者を返すようにすることです。そうすることで、この流暢な文章を残すことができます。 – Joel

答えて

0

多分私はこれを受け入れる方法を見つけました。私がここで行う必要があるのは、Observableインスタンシエーションそのものの外側での二重バインディングです。例えば。私はお互いにカウントされDbObservableとDbOnSubscribeペアを必要とする、このような何か:

DbObservableクラス:

public class DbObservable<T> extends Observable<T> { 

    //Some parameter 
    private String sql; 

    protected DbObservable(DbOnSubscribe<T> onSub) { 
     super(onSub); 
    } 

    //Getter for DbOnSubscribe 
    public String getSql() { 
     return sql; 
    } 

    //Chain parameter modifier 
    public DbObservable<T> sql(String sql) { 
     this.sql = sql; 
     return this; 
    } 
} 

DbOnSubscribeクラス:

public class DbOnSubscribe<T> implements Observable.OnSubscribe<T> { 

    private DbObservable<T> dbObservable; 

    @Override 
    public void call(Subscriber<? super T> subscriber) { 
     String sql = dbObservable.getSql(); //Access SQL param 
     subscriber.onNext((T) sql); //Use subscriber 
     subscriber.onCompleted(); 
    } 

    //Set back-reference 
    public void setDbObservable(DbObservable<T> dbObservable) { 
     this.dbObservable = dbObservable; 
    } 
} 

そして最後に、当社の仮定DbConnectorクラス:

public class DbConnector { 

    public DbObservable<String> getObservable() { 
     DbOnSubscribe<String> onSub = new DbOnSubscribe<String>(); 
     DbObservable<String> obs = new DbObservable<>(onSub); 
     onSub.setDbObservable(obs); 
     return obs; 
    } 
} 

だから私が試してみると...

public class DbObservableTest { 

    public static void main(String[] args) { 
     DbConnector srcDb = new DbConnector(); 

     srcDb.getObservable() 
       .sql("some SQL") 
       .subscribe(System.out::println); 
    } 
} 

...本当にうまくいきます!それは "いくつかのSQL"を表示します。あなたはスーパークリーンになりたいと、コードの1本のまたは2の余分なラインを気にしない場合はジョエルとTassos Bassoukosによって提案されているように、ビルダーのために行く

結論

  1. あなたは(常にどこかにカプセル化されなければならない)もう少し複雑なコードを恐れていないよ、あなたは本当にこれらのパラメータは、あなた自身の観察可能な内になりたい場合は、任意のより多くの
  2. 二重結合の方法を試すことができますオプション?
2

あなたがそれを行うことができます2つの方法があります:

オプション#1:あなた自身のオブジェクトが設定を行う必要があり、その後、​​、query()またはドメインスイッチtoObservable()あります

srcDb 
.find(Bean.class) 
.sql(selectSql) 
.params(selectParams) 
.execute() 
.subscribe(
     trgDb.getSubscriber(Bean.class) 
      .sql(insertSql) 
); 

オプション#を2:再使用する一般的な操作に.compose()を使用します。

srcDb 
.getObservable(Bean.class) 
.compose(addSQLParameters()) 
.subscribe(
     trgDb.getSubscriber(Bean.class) 
      .sql(insertSql) 
); 

<T> Transformer<T,T> addSQLParameters() { 
    return obs -> obs.sql(selectSql).params(selectParams); 
} 

私はあなたがオプション#1を使用することをお勧め、コードの一部をよりよく管理できるようになります。

+0

あなたとジョエル(彼のコメント付き)はおそらく正しいでしょう。私はリフレクションを使用して親クラスからonSubscribeフィールドを公開する実験をいくつか試みてみましたが、これは実際に私が欲しいものを正確に行うことを可能にしましたが、それはきれいな解決策ではありません。とにかく、RxJavaがObservableのいくつかのバージョンを提供していれば、開発者は「自分が行っていることを知っている」と主張するgetOnSubscribe()メソッドを提供することができます。 – LittleLight

+0

'RxJavaHooks#setOnObservableCreate'に興味があるかもしれませんが、* all * observablesに当てはまることに留意してください。 IMOではXY問題が発生しています。観測値を作成する前に設定を行うだけです。 –

+0

ありがとう、私はそれを調べます:-)。 – LittleLight

関連する問題