Rxjava2-小白入門(一)

前言

最近在學(xué)習(xí)Rxjava2,雖然在實際的項目中使用也看了很多的文章和文檔,學(xué)會的了如何使用但是忘記的很快,也沒有很好的總結(jié),在學(xué)習(xí)的時做的筆記過了一段時間發(fā)現(xiàn)自己做的筆記都有些看不明白,作為小白的我寫博客還是有點膽戰(zhàn)心驚的,這篇博客的主要的目的是引導(dǎo)沒有了解過Rxjava的人一個參考,講一些簡單的原理和常用操作符及使用場景,可能會有錯誤希望大家多多指教批評,去其糟粕取其精華,那么開始學(xué)習(xí)之旅吧。


概念

我們知道Rxjva使用的是觀察者設(shè)計模式,那么什么是觀察者模式呢?其實我們在開發(fā)中一直使用,只是我們沒用認(rèn)真的去了解,常見按鈕點擊事件就是一個很好的例子。也許現(xiàn)在你還疑惑那么在我講解概念之后回頭在看你就會明白了。首先我們要先了解幾個概念。


  • 什么是觀察者模式?

觀察者(Observer)模式:是對象的行為模式,又叫做發(fā)布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監(jiān)聽(Source/Listener)模式或者從屬(Dependents)模式。

抽象主題(Subject)角色:
抽象主題角色把所有對觀察者對象的引用保存在一個聚集(比如ArrayList對象)里,每個主題都可以有任何數(shù)量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象,抽象主題角色又叫做抽象被觀察者(Observable)角色。

具體主題(ConcreteSubject)角色:
將有關(guān)狀態(tài)存入具體觀察者對象;在具體主題的內(nèi)部狀態(tài)改變時,給所有登記過的觀察者發(fā)出通知。具體主題角色又叫做具體被觀察者(Concrete Observable)角色。

抽象觀察者(Observer)角色:
為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己,這個接口叫做更新接口。

具體觀察者(ConcreteObserver)角色:
存儲與主題的狀態(tài)自恰的狀態(tài)。具體觀察者角色實現(xiàn)抽象觀察者角色所要求的更新接口,以便使本身的狀態(tài)與主題的狀態(tài) 像協(xié)調(diào)。如果需要,具體觀察者角色可以保持一個指向具體主題對象的引用。

觀察者模式定義了一種一對多的依賴關(guān)系,讓多個觀察者對象同時監(jiān)聽某一個主題對象,這個主題對象在狀態(tài)上發(fā)生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。

這是一種比較官方的說法,當(dāng)然每個人的理解不同。簡單來說在觀察者模式中,有兩個對象觀察者(訂閱)和被觀察者(被訂閱),一個被觀察者可以有很多觀察者,當(dāng)被觀察者法神變化的時候,所有的觀察者都會收到通知,從而改變自己(更新自己)。舉個例子:一個課堂上,只會有一個老師(被觀察者)講課,當(dāng)講到一個知識點,每個都同學(xué)(觀察者)聽到老師所講的知識點,有的會做筆記有的會提問(相當(dāng)于所有觀察者接到通知改變自己)。這就是觀察者模式。

  • 是觀察者模式圖形分析?
觀察者模式

抽象主題(Subject)角色:
抽象主題角色把所有對觀察者對象的引用保存在一個聚集(比如ArrayList對象)里,每個主題都可以有任何數(shù)量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象,抽象主題角色又叫做抽象被觀察者(Observable)角色。

具體主題(ConcreteSubject)角色:
將有關(guān)狀態(tài)存入具體觀察者對象;在具體主題的內(nèi)部狀態(tài)改變時,給所有登記過的觀察者發(fā)出通知。具體主題角色又叫做具體被觀察者(Concrete Observable)角色。

抽象觀察者(Observer)角色:
為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己,這個接口叫做更新接口。

具體觀察者(ConcreteObserver)角色:
存儲與主題的狀態(tài)自恰的狀態(tài)。具體觀察者角色實現(xiàn)抽象觀察者角色所要求的更新接口,以便使本身的狀態(tài)與主題的狀態(tài) 像協(xié)調(diào)。如果需要,具體觀察者角色可以保持一個指向具體主題對象的引用。

從這個關(guān)系圖我們可以看出左側(cè)是被觀察者(Subject/Observable),右側(cè)是觀察者(Observer),他們的關(guān)系是1-0..*(1對多的關(guān)系)。被觀察者通過集合管理觀察者,并且有三個方法:attach()綁定(add()加入集合) detached()解綁(remove()移除集合) notifiyObeserver()通知所有的觀察者(遍歷集合調(diào)用updata()方法)。

明白了關(guān)系圖那么我們通過代碼來實際運用下加深理解:

/**
 * 觀察者
 */
public interface Observer {

    void upData(String state);

}

首先我們創(chuàng)建一個觀察者,他只用一個方法upData(String state);更新狀態(tài)。我們在創(chuàng)建兩個類來繼承它。

public class TomObserver implements Observer{

    @Override
    public void upData(String state) {

        /*
         * 在這里我們根據(jù)接受到state做相應(yīng)的處理
         */
        System.out.println("我是Tom 我在"+state);
    }


}

public class JackObserver implements Observer{

    @Override
    public void upData(String state) {
        /*
         * 在這里我們根據(jù)接受到state做相應(yīng)的處理
         */
        System.out.println("我是Jack 我在"+state);
    }

}

在這里我們創(chuàng)建2個觀察者子類Tom和Jack。實現(xiàn)upData()并根據(jù)介紹到的state做相應(yīng)的處理,這里我們只是簡單的打印接到信息。

觀察者創(chuàng)建完成我們在創(chuàng)建被觀察者(Subject/Observable)。

/**
 *被觀察者
 */
public abstract class Observable {

    List<Observer> list=new ArrayList<>();
    /*
     * 綁定觀察者
     */
    public void attach(Observer observer){
        list.add(observer);
        System.out.println("綁定觀察者"+observer.getClass().getSimpleName());
    }
    
    /*
     * 解綁觀察者
     */
    public void detach(Observer observer){
        list.remove(observer);
        System.out.println("解綁被觀察者"+observer.getClass().getSimpleName());
    }

    /*
     * 通知所有觀察者
     */
    public void notifyObservers(String state){
        for (Observer observer : list) {
            observer.upData(state);
        }
    }
}

這段代碼也很容易理解,就是和上面我們的關(guān)系圖一樣被觀察者通過集合管理觀察者。通過綁定添加,解綁移除,notifyObservers()通知所有觀察者。我們在創(chuàng)建一個他的子類。

public class MessageOberver extends Observable{
    
    public void change(String state){
        notifyObservers(state);
    }

}

創(chuàng)建子類的,其實它就做了一件事就是調(diào)用父類的notifyObservers()方法。

好了?,F(xiàn)在所有的準(zhǔn)備工作我們已經(jīng)做好了讓我們來實際操作一下,到底是怎么運作的。

public class Test {

    public static void main(String[] args) {
        Observer jObserver=new JackObserver();
        
        Observer tObserver=new TomObserver();
        
        MessageOberver oberver=new MessageOberver();
        
        oberver.attach(jObserver);
        oberver.attach(tObserver);
        oberver.change("打籃球");  
        
        oberver.detach(tObserver);
        
        oberver.change("跑步");
    }
}

這段代碼我們先創(chuàng)建2個Observer(觀察者)實例,再創(chuàng)建MessageOberver(被觀察者)通過attach()綁定,當(dāng)我們被觀察者(再創(chuàng)建MessageOberver),狀態(tài)改變("打籃球")看看會發(fā)生什么?

綁定觀察者JackObserver
綁定觀察者TomObserver
我是Jack 我正在打籃球
我是Tom 我正在打籃球
解綁被觀察者TomObserver
我是Jack 我正在跑步

可以看到當(dāng)我們的被觀察者狀態(tài)改變要去打籃球的時候,所有他的觀察者(也就是attach()綁定的對象)都能接到信息,當(dāng)我們解綁的后解綁的觀察者就不能在接到信息了。這就是我們的觀察者模式。其實這么看來還是挺簡單的。

在理解了觀察者模式后我們在回到文章開始的時候提到的android中用的觀察者模式比如點擊事件,放到我們寫的例子中我們應(yīng)該怎么去理解呢?

public class Test {

    public static void main(String[] args) {
        Observer jObserver=new JackObserver();
        
        Observer tObserver=new TomObserver();
        
        MessageOberver oberver=new MessageOberver();
        /*
         * oberver相當(dāng)于Button
         * attach相當(dāng)與setOnclickListener
         * jObserver相當(dāng)于 OnclickListener
         * change方法就是我們在監(jiān)聽中對應(yīng)的要做的事情(這里我們是調(diào)用notifyObservers(),
         * 它的內(nèi)部是調(diào)用每個oberver的updata方法 我們可以在updata方法中做不同的處理)
         */
        oberver.attach(jObserver);
        oberver.attach(tObserver);
        oberver.change("打籃球");
        
        oberver.detach(tObserver);
        
        oberver.change("跑步");
        
    }
}

看了我的注釋在結(jié)合平時我們寫的代碼是不是有一種不約而同的感覺呢。那么在實際開發(fā)中我們又在那里用到觀察者模式呢?簡單的例子。其實在實際項目中我們想讓多個界面監(jiān)聽一個對象的狀態(tài)變化時我們就可以用到觀察者模式。比如常見的下載應(yīng)用我隨便找的兩個截圖

image
image

這是我們常見手機應(yīng)用軟件的截圖這是兩個不同的頁面,2個頁面下載進(jìn)度同步,其實我們就可以使用觀察者模式,下載任務(wù)為被觀察者頁面(Activity或者Fragment)為觀察者(實現(xiàn)接口,參數(shù)將String state 該改成DownInfo info下載任務(wù))那么當(dāng)下載進(jìn)度改變時我們實時跟新狀態(tài),那么兩個頁面的進(jìn)度同步啦,比如音樂播放進(jìn)度等根據(jù)業(yè)務(wù)要求觀察者設(shè)計模式有時會幫助我們解決不少場景需要。

結(jié)語

這篇文章主要是講解什么觀察者模式,雖然本文是Rxjava小白入門,但是講下觀察者模式還是有必要的。雖然網(wǎng)上也有很多講解,有的講的太深,有的講的太多,并不是他們說的不好,而是身為小白的我去讀太深的東西讓我難以記住和理解,希望這篇文對你有所幫助。下篇文章我會簡單講解下java中的觀察者模式和Rxjava的簡單使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,093評論 1 15
  • 前言 上篇文章我們主要講解了觀察者模式。那么這節(jié)課我們主要講解Rxjava2的基本使用和操作符。其實網(wǎng)上的關(guān)于Rx...
    g小志閱讀 627評論 0 2
  • 前言 繼續(xù)上篇的Rxjava2的入門實例,把剩下的運用Rxjava的實例講下,首先要說名下本文會用到Rxbindi...
    g小志閱讀 809評論 1 3
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,697評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,564評論 19 139

友情鏈接更多精彩內(nèi)容