4

Yea, that may sound a bit ambitious but here is what I want to achieve:

I have class which holds my hot Observable, it takes some time for class to prepare it correctly (create it in another place and obtain reference), so when another class asks for it, reference may be still null (causing nullpointer). What I'm trying to achieve is similiar to NullObject pattern: return empty observable (instead of null) which can be safely subscribed, and when Observable is created properly start emitting items.

The one way to solve it is to create PublishSubject which acts as bridge between client classes and ObservableHolder class. PublishSubject reference is always returned to client, and when Observable is ready it will just forward all events to subject. Is that a good solution? Or it can be done better?

@edit

I've decided to stay with my solution, I think after wrapping it in class it's good enough solution. I upvoted the below answer, however it's not matching my problem because it's not directly related to rx-java implementation however suggesting a proxy pattern was helpfull.

2
  • 1
    PublishSubject is a simple way to achieve this generally. If you want to tell more about how the observable is prepared, maybe we can devise a Subject-less solution as well. Commented Nov 10, 2015 at 22:29
  • PublishSubject seems reasonable. One more solution that comes to mind is to make your observable preparation method return an Observable<Observable<T>>, but doesn't look as clean as the implementation with a subject. Commented Nov 11, 2015 at 5:01

1 Answer 1

1

I guess what you are looking for is called proxy pattern.

A proxy is (as the name implies) an object that takes place of another object that is not available at the moment.

You might want to implement it using java.util.Observable in this way

public class ObservableProxy extends Observable {


    private ObservableProxyAdapter observableProxyAdapter = new ObservableProxyAdapter();

    private Observable target;

    public void setTarget(Observable target) {
        if(this.target != null){
            // if this proxy was connected to an observer... disconnect
            this.target.deleteObserver(observableProxyAdapter);
        }

        this.target = target;

        if(this.target != null){
            // If a new target is set... connect to it
            this.target.addObserver(observableProxyAdapter);
        }
    }


    private class ObservableProxyAdapter implements Observer {

        public void update(Observable o, Object arg) {
            // forward notifications from the target
            setChanged();
            notifyObservers(arg);

        }

    }

}

You hand out the ObservableProxy to clients. Clients can register themselves to the ObservableProxy. Later when the 'real' Observable becomes available, you can set it as the target of the ObservableProxy. The proxy registers itself as an Observer to the target and forwards notifications to it's Observers.

+-----------------+  notify  +---------------+   notify   +--------------+
| real observable |  ------> | proxy adapter |   ------>  | observables  |
+-----------------+          +---------------+            |  of proxy    |
                                                          +--------------+

Here is an example application

public class ObservableProxyTest {

    public static void main(String[] args) {
        ObservableProxy observableProxy = new ObservableProxy();

        Observer someObserver = new Observer() {

            public void update(Observable o, Object arg) {
                System.out.println(arg);
            }
        };
        observableProxy.addObserver(someObserver);


        // Later the real observer becomes available
        RealObservable realProxy = new RealObservable();
        observableProxy.setTarget(realProxy);


        // notifications will be forwarded
        realProxy.notifyHello();
    }

    private static class RealObservable extends Observable {

        public void notifyHello(){
            setChanged();
            super.notifyObservers("Hello World");
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.