本文首發於 vivo互聯網技術 微信公衆號
連接: https://mp.weixin.qq.com/s/duO1pAfaKUI2_x_GVvZHMg
做者:Yunjie Ma
ReactiveX 的全稱爲Reactive Extension,通常縮寫爲 Rx,即咱們日常所說的反應式編程。其設計原理主要使用了觀察者模式,區分數據的生產者和消費者,經過事件流的方式進行數據的異步處理。java
RxJava 是 ReactiveX Java語言的實現,其編程體驗與Java 8中的函數式編程和流(Stream)有很大的類似之處,在掌握了Java8的相關知識後,你能夠很輕鬆的就上手使用 RxJava。編程
本篇文章主要聚焦對RxJava中幾種主要的設計模式的理解,經過梳理Observable的相關類圖以及講解這些類之間的關係,讓你們可以更清晰的理解RxJava中事件驅動的工做原理。設計模式
首先咱們寫一個簡單的RxJava的程序,把數組中的元素做爲事件發送,最終由消費者打印在控制檯:數組
咱們以這段簡單的代碼爲基礎,講解下貫穿整個ReactiveX設計的四個概念:觀察者,被觀察者,事件,訂閱。微信
對上述代碼進行時序分析,能夠清晰的看出這一段代碼的運行過程,最終由FromArrayDisposable生產了onNext和onComplete事件,並通知Observer進行消費。異步
與此同時,咱們也看到,簡單的一行代碼,居然涉及這麼多類的交互,若是增長一些其餘的操做符,咱們對整個程序把控起來就沒那麼容易了,下面咱們將經過分析RxJava中的一些主要的設計模式,剖析類與類的關聯關係,來更清晰地理解RxJava的工做原理。函數式編程
在整個數據處理的過程當中,Observable能夠說是最重要的一個對象。從上面的時序圖能夠看出,客戶端(消息的生產者或者消費者)只和Observable進行交互,觀察者和被觀察者之間關係的建立也是由Observable去實現,而不用咱們顯示的編碼實現,這大大下降了咱們使用觀察者模式的成本。函數
那麼Observable主要有哪些做用呢,咱們首先來看下和Observable相關的類圖:編碼
從圖中咱們能夠看出:spa
Observable的存在讓生產者和消費者徹底的解耦了,生產者只需關注本身生成何種Observable對象,而消費者也只需關注本身觀察的是哪一種Observable。
在實際的應用中,Rxjava已經提供了各類各樣的操做符供咱們使用,生產者只須要調用Observable中相應的方法便可以生成所需的可觀察對象,供消費者進行事件訂閱。消費者只需調用可觀察對象的subscribe()方法便可與生產者創建觀察關係,極其方便。
觀察者模式是RxJava設計的核心思想,在觀察者模式中老是存在觀察的對象和被觀察的對象,從上文的解析中也能夠看出Observable更多的是一個控制器的做用,而並不是真正的事件的來源。那麼在RxJava中,什麼纔是真正的生產者,什麼纔是真正的消費者呢。
咱們來分析下如下三種常見的Observable:
先簡單介紹下這幾個Observable的做用,fromArray的做用是將數組中的元素做爲onNext事件發送,create的做用是發送自定義事件,just的做用是發送單個事件。
上一小節有講到實際的訂閱行爲是由各個Observable類中subscribeActual()方法實現的,咱們來看下這三個類的subscribeActual()方法。
除去細枝末節,這三個方法均可以分紅如下三步
下圖是整個流程中的相關類圖。實際事件的發送者是FromArrayDisposable等對象,而實際的觀察者,則是一個實現了Observer接口的實體類。若是咱們在subscribe時傳入的是一個lambda表達式,以後會被包裝成一個默認的LambdaObserver對象,進行事件消費。
RxJava中提供了豐富的操做符,好比flatMap,concatMap等能夠對事件轉換,subscribeOn,observableOn等能夠對生產和消費的線程進行控制。這些操做符實際上調用了Observable中的包裝方法對原有的可觀察對象進行包裝,返回了一個加強了的可觀察對象。
操做符種類繁多,在這就不一一舉例,咱們以flatMap爲例,分析一下這些操做符是如何工做的。
首先,flatMap操做會返回一個ObservableFlatMap對象,在建立這個對象時,會將原始的Observable對象做爲構造函數的參數傳入。
查看其核心方法subscribeActual,
能夠看到這一類對象的subscribeActual方法和上一節中的方法不太同樣,這裏面並無去實際的建立觀察關係,而是作了兩件事:
Observable是支持鏈式操做的,就和Java 8中的Stream同樣,咱們來考慮這樣一行代碼。
咱們在分析上面這串代碼時,必定會凌亂很是,在看源碼時也會看到前面忘掉後面,可是若是咱們對RxJava的包裝流程足夠了解的話,就能夠很輕鬆的對上述代碼進行分析。
RxJava的封裝足夠強大,可讓咱們很方便的進行使用和擴展,但這也給咱們理解其真實的工做原理帶來了難度,若是咱們對整個事件的處理過程處於只知其一;不知其二的狀態,那咱們就沒法從容的對服務進行異步編排,在實際開發過程當中也難以發現問題的根源。
本文主要分析了RxJava中主要的設計模式,其中有模板模式、工廠模式、觀察者模式、裝飾器模式,理解了這些設計模式,理解了RxJava中類與類的關係,咱們就可以對整個事件的處理流程瞭然於胸,分析代碼時也可以事半功倍。