Как получить шаблон NullObject с помощью RxJava

Да, это может показаться немного амбициозным, но вот чего я хочу добиться:

У меня есть класс, который содержит мой горячий Observable, классу требуется некоторое время, чтобы подготовить его правильно (создать его в другом месте и получить ссылку), поэтому, когда другой класс запрашивает его, ссылка может быть все еще нулевой (вызывая нулевой указатель). То, чего я пытаюсь добиться, похоже на шаблон NullObject: вернуть пустое наблюдаемое (вместо null), на которое можно безопасно подписаться, и когда Observable создан правильно, начать испускать элементы.

Единственный способ решить эту проблему — создать PublishSubject, который действует как мост между клиентскими классами и классом ObservableHolder. Ссылка PublishSubject всегда возвращается клиенту, и когда Observable будет готова, он просто перенаправит все события в тему. Это хорошее решение? Или можно сделать лучше?

@изменить

Я решил остаться со своим решением, я думаю, что после его обертывания в классе это достаточно хорошее решение. Я проголосовал за приведенный ниже ответ, однако он не соответствует моей проблеме, поскольку не имеет прямого отношения к реализации rx-java, однако было полезно предложить шаблон прокси.


person Than    schedule 10.11.2015    source источник
comment
PublishSubject - это простой способ добиться этого в целом. Если вы хотите рассказать больше о том, как подготавливается наблюдаемое, возможно, мы также сможем разработать беспредметное решение.   -  person akarnokd    schedule 11.11.2015
comment
PublishSubject кажется разумным. Еще одно решение, которое приходит на ум, — сделать так, чтобы ваш наблюдаемый метод подготовки возвращал Observable<Observable<T>>, но выглядел не так чисто, как реализация с субъектом.   -  person AndroidEx    schedule 11.11.2015


Ответы (1)


Я думаю, то, что вы ищете, называется шаблон прокси.

Прокси — это (как следует из названия) объект, который заменяет другой объект, недоступный в данный момент.

Возможно, вы захотите реализовать его с помощью java.util.Observable таким образом.

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);

        }

    }

}

Вы раздаете ObservableProxy клиентам. Клиенты могут зарегистрироваться в ObservableProxy. Позже, когда «настоящий» Observable станет доступным, вы сможете установить его в качестве цели ObservableProxy. Прокси регистрирует себя как Observer для цели и пересылает уведомления своим наблюдателям.

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

Вот пример приложения

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");
        }
    }
}
person René Link    schedule 10.11.2015