RxJava觀察者模式

語言: CN / TW / HK

theme: cyanosis


開啟掘金成長之旅!這是我參與「掘金日新計劃 · 12 月更文挑戰」的第33天,點擊查看活動詳情

1.RxJava的觀察者模式

RxJava的觀察者模式是擴展的觀察者模式,擴展的地方主要體現在事件通知的方式有很多種

2.RxJava的觀察者模式涉及到幾個類

  • Observable:被觀察者
  • Observer:觀察者
  • Subscribe:訂閲
  • Event:被觀察者通知觀察者的事件

3.Obsercerable與Observer通過Subscribe實現關聯,Event主要向Observer通知Observeble的變化,Event有幾個通知方式

  • Next:常規事件,可以傳遞各種各樣的數據
  • Error:異常事件,當被觀察者發送異常事件後那麼其他的事件就不會再繼續發送了
  • Completed:結束事件,當觀察者接收到這個事件後就不會再接收後續被觀察者發送過來的事件

4.代碼實現

  • 首先定義一個觀察者Observer

``` public abstract class Observer { //和被觀察者訂閲後,會回調這個方法 public static void onSubscribe(Emitter emitter);

 // 傳遞常規事件,用於傳遞數據
public abstract void onNext(T t);

// 傳遞異常事件
public abstract void onError(Throwable e);

// 傳遞結束事件
public abstract void onComplete();

}

Observer中的方法都是回調,其中多了一個Emitter的接口類,他是一個發射器

public interface Emitter {

void onNext(T t);

void onError(Throwable error);

void onCompleted();

}

實現邏輯就是通過包裝Observer,裏面最終是通過Observer進行回調的

public class CreateEmitter implements Emitter {

final Observer<T> observer;

CreateEmitter(Observer<T> observer) {
    this.observer = observer;
}

 @Override
public void onNext(T t) {
    observer.onNext(t);
}

@Override
public void onError(Throwable error) {
    observer.onError(error);
}

@Override
public void onComplete() {
    observer.onComplete();
}

}
```

  • 被觀察者的實現

``` public abstract class Observable{

public void subscribe(Observer<T> observer) {
    //通過傳入的Observer包裝成CreateEmitter,用於回調
    CreateEmitter emitter = new CreateEmitter(observer);

    //回調訂閲成功的方法
    observer.onSubscribe(emitter);

    //回調發射器emitter
    subscribe(emitter);
}

/**
*   訂閲成功後,進行回調
*/
public abstract void subscribe(Emitter<T> emitter);

}

就兩步,第一步用於訂閲,第二步用於回調 ```

  • 具體的使用

``` private void observer() { // 第一步,創建被觀察者 Observable observable = new Observable() { @Override public void subscribe(Emitter emitter) { emitter.onNext("第一次");

            emitter.onNext("第二次");

            emitter.onNext("第三次");

            emitter.onComplete();
        }
    };

// 第二步,創建觀察者
Observer<String> observer = new Observer<String>() {
        @Override
        public void onSubscribe(Emitter emitter) {
            Log.i("TAG", " onSubscribe ");
        }

        @Override
        public void onNext(String s) {
            Log.i("TAG", " onNext s:" + s);
        }

        @Override
        public void onError(Throwable e) {
            Log.i("TAG", " onError e:" + e.toString());
        }

        @Override
        public void onComplete() {
            Log.i("TAG", " onComplete ");
        }
    };

// 第三步,被觀察者訂閲觀察者
observable.subscribe(observer);

}

被訂閲成功後,被觀察者的subscribe裏面就可以通過發射器發送事件了,最終在觀察者的方法裏進行回調。 ```

RxJava也是觀察者和被觀察者訂閲的過程,只不過被觀察者有變化的時候是由發射器進行發送的,這樣就不止有一種事件了

1.RxJava的裝飾者模式

    • 裝飾者模式:在不改變原有的架構基礎上添加一些新的功能,是作為其原有結構的包裝,這個過程稱為裝飾。
    • RxJava的裝飾者模式主要是用於實現Observable和Observer的包裝,主要是為了與RxJava的觀察者模式配合實現代碼的方式更簡潔。
    • 拆解RxJava的裝飾器模式
      • 被觀察者Observable

``` 參考手機包裝的例子 第一步:要有一個抽象接口,在RxJava中這個抽象接口是ObservableSource,裏面有一個方法subscribe

public interface ObservableSource {

/**
 * Subscribes the given Observer to this ObservableSource instance.
 * @param observer the Observer, not null
 * @throws NullPointerException if {@code observer} is null
 */
void subscribe(@NonNull Observer<? super T> observer);

}

第二步:要有一個包裝類,實現了ObservableSource的,RxJava的包裝類是Observable,實現了對應的接口, 並且在subscribe方法裏通過調用抽象方法subscribeActual,來對觀察者進行訂閲 public abstract class Observable implements ObservableSource { ...

@Override
public final void subscribe(Observer<? super T> observer) {
    ...
     subscribeActual(observer);
    ...
}

protected abstract void subscribeActual(Observer<? super T> observer);
...

}

第三步:這就是具體的包裝類瞭如圖所示 ```

2.觀察者Observer:

  • 第一步:要有一個抽象接口,而RxJava的接口是Emitter和Observer,裏面有好幾個方法基本一樣,onNext,onError,onComplete,用於被觀察者進行回調;
  • 第二步:要有一個包裝類,實現了Emitter或者Observer,但是觀察者比較特殊,沒有一個基礎的包裝類,而是直接封裝了很多的包裝類

RxJava的的被觀察者是在創建的時候進行包裝的,例如第一步的Observable.create方法,通過Observable.create的創建後進行了第一層包裝,結構如下

第二步的subscribeO方法調用時進行了第二層的包裝,此時結構如下:

第三步的observerOn方法調用時,進行了第四層的包裝,那麼結構就是下面的樣子

最終調用訂閲方法的時候已經進行了四次包裝,那麼可以理解每調用一次操作符就會進行一層被觀察者的包裝。

那麼這樣包裝的好處是什麼呢?

這就是裝飾者模式的特性,在不改變原有功能的基礎上添加額外的功能。

5.總結

我們在創建被觀察者的時候,會對被觀察者做一層包裝,創建幾次就包裝幾次,然後在被觀察者調用subscribe方法時,一層層回調被觀察者的subscribeAcutal方法,而在被觀察者的subscribeAcutal方法裏,會對觀察者做一層包裝;

也就是説被觀察者是在創建的時候進行包裝,然後在subscribeActual中實現額外的功能;

而觀察者是在被觀察者調用subscribeActual方法裏進行包裝的,然後針對觀察者實現自己額外的功能;

流程圖如下: