ReactiveX / RxJava

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Apache License 2.0
47.93k stars 7.6k forks source link

How to extend Rx Subjects? #1034

Closed lexer closed 10 years ago

lexer commented 10 years ago

I want to create my own subject similar to BehaviorSubject, but with sync method to get last value.

Look like all classes are internal and it's very hard to extend or create own implementation of Subject

Any advice what base classes I should use for creating my custom subjects?

lexer commented 10 years ago

Currently implemented it this way.

public final class ReactiveProperty<T> extends Subject<T, T> {
    private BehaviorSubject<T> subject;
    private T value;

    public static <T> ReactiveProperty<T> create(T value) {
        final BehaviorSubject<T> subject = BehaviorSubject.create(value);

        OnSubscribe<T> onSubscribe = new OnSubscribe<T>() {
            @Override
            public void call(Subscriber<? super T> subscriber) {
                subject.subscribe(subscriber);
            }
        };

        return new ReactiveProperty<T>(onSubscribe, subject, value);
    }

    protected ReactiveProperty(OnSubscribe<T> onSubscribe, BehaviorSubject<T> subject, T value) {

        super(onSubscribe);
        this.subject = subject;
        this.value = value;
    }

    public T get() {
        return value;
    }

    @Override
    public void onCompleted() {
        subject.onCompleted();
    }

    @Override
    public void onError(Throwable e) {
        subject.onError(e);
    }

    @Override
    public void onNext(T newValue) {
        if (!newValue.equals(value)) {
            value = newValue;
            subject.onNext(newValue);
        }
    }
}
benjchristensen commented 10 years ago

I have kept SubjectSubscriptionManager private as I don't trust its public API. Evidence of this is shown here: https://github.com/Netflix/RxJava/pull/1040 It's also very complicated to use so I don't think I ever want to expose it as part of the public API.

The way you've done it by building on top of an existing Subject is far easier.

lexer commented 10 years ago

@benjchristensen if my implementation is the way to do it i will close this issue.

benjchristensen commented 10 years ago

I think it's a good approach, using the basic Subject implementations as building blocks, and not trying to recreate the subscription management stuff. Unless a use case shows up that can't be done this way let's stick with this.