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方法裡進行包裝的,然後針對觀察者實現自己額外的功能;

流程圖如下: