2017-02-09 16 views
2

私は特定のタイプのイベントを投稿し、オブジェクトクラスに応じてそれらを聞くことができるRxBusを実装しようとしています。 BehaviorSubjectを使用して、スティッキーイベント(サブスクリプションの前でも投稿できます)をサポートしています。そして、粘着性のイベントは、各タイプごとに保持する必要があります。コードは次のとおりです。RxJava:特定のタイプのBehaviorSubject

private final Subject<BaseEvent, BaseEvent> bus = new SerializedSubject<>(BehaviorSubject.create()); 

public <E extends BaseEvent> void post(E event) { 
    bus.onNext(event); 
} 

public <E extends BaseEvent> Observable<E> observe(Class<E> eventClass) { 
    return bus.asObservable().ofType(eventClass); 
} 

これは、1つのタイプのイベントでうまく動作します。しかし、より多くの異なるイベントがあり、最後に投稿されたイベントが私が購読しているものと異なるタイプのものである場合、BehaviorSubjectはタイプに依存しない最後のイベントだけを保持するため、ofType()によってフィルタリングされます。

私は2つの解決策を考えていた:各タイプの対象のマップを作成するには

  1. が、サブタイプとの問題があります。
  2. ReplaySubjectを使用し、ofType()およびdistinct()を使用してイベントをフィルタリングするには。しかし、私は、サブスクリプションの前後に放出されたイベントを区別する方法を見つけることができません。

これらのソリューションを動作させる方法はあるのでしょうか、それとも私が何か不足していて、それを実装するより良い方法がありますか?

答えて

1

まず、Subjectは不要ですが、Relayです。

私はあなたに3つ目の解決策を提案します:すべての異なるイベントを覚えている独自のリレー(またはサブジェクト)の実装を書くこと。あなたは既存の実装(ここでは、PublishRelay)に頼ることができ、ゼロからリレーまたは件名を書き換える必要はありません。

import com.jakewharton.rxrelay2.PublishRelay; 
import com.jakewharton.rxrelay2.Relay; 

import java.util.HashMap; 
import java.util.Map; 

import io.reactivex.Observer; 

public class RxBus extends Relay<Object> { 

    private PublishRelay<Object> concreteRelay = PublishRelay.create(); 
    private Map<Class, Object> stickyEvents = new HashMap<>(); 

    public <T> T getSticky(Class<T> type) { 
     return (T)stickyEvents.get(type); 
    } 

    @Override 
    public void accept(Object value) { 
     stickyEvents.put(value.getClass(), value); 
     concreteRelay.accept(value); 
    } 

    @Override 
    public boolean hasObservers() { 
     return concreteRelay.hasObservers(); 
    } 

    @Override 
    protected void subscribeActual(Observer<? super Object> observer) { 
     concreteRelay.subscribeActual(observer); 
    } 
} 
+0

おかげで、主被写体とは別に、粘着性のイベントを維持するという考えは起こりませんでした私に。 :) –

関連する問題