Rxjava源码解析笔记 | Rxjava概述 & 传统观察者设计模式源码解析

进行耗时任务

比如:在后台做一些网络操作、查询或者一些复杂计算的时候,
我们如果不用其他框架的话,
最常见做法即自己开一个子线程
然后通过回调的形式获取到结果(如后台以结果为参数发送广播,前台回调onReceive()接收获取到结果);

但是这样有一个问题,
随着业务逻辑越来越复杂,
项目会陷入回调中套回调的病区
这对后期维护代码来说是一个很严重的问题;



而Rxjava的出现解决了以上的问题

  • Rxjava本质上是一个异步操作库
    它是一个能用非常简单的逻辑,去处理那些繁琐复杂任务
    异步的操作事件库;
    Rxjava在一定的程度上,
    也能替代项目中非常多的Handler、AsyncTask等等;


关于Rxjava的设计模式——观察者模式

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新;

  • 在app开发中,如果有一个对象的状态/数据,是你非常要关心的,
    同时你每个页面所有的UI都会跟这个对象绑定,
    即当这个对象发生改变的时候,我们就需要通知所有的页面都去做UI改变;
    以上所述其实便是一种观察者模式
    A对象对B对象的数据高度敏感,
    当B对象变化的一瞬间,A对象要做出反应;
    这时候A对象就是观察者,B对象就是被观察者;

    观察者模式的情况,
    就是众多的观察者,对被观察者的数据 高度敏感,
    被观察者变化之后观察者自身的一种反应,
    它是一种一对多的关系,多个观察者对应一个被观察者;
  • 观察者模式的UML类图

    • Observerable(被观察者接口,interface):

      • registerObserver():将观察者注册到被观察者当中;即订阅方法;
      • removeObserver():将观察者从被观察者中移出;取消订阅方法;
      • notifyObservers():当我们被观察者状态改变的时候,这个方法就会被调用;
        而此方法内部又会调用观察者接口(Observer)update()方法,
        去通知观察者(Observer)做出相应的处理改变;
    • ConcreteObserverable(被观察者具体的实现,class)

      • 实现了Observerable(被观察者接口,interface)定义的三个方法;
      • 定义了List<Observer>,用于保存注册好的观察者;
        泛型是Observer,是接口,而非具体的实现类,
        这样做的原因就是,
        为了让一个被观察者实例,
        可以对应着,可能会有的,
        多个实现了Observer(观察者)接口的观察者实现类,

        (一个被观察者实例可以对应多个观察者实现类实例
        如此便可把观察者和被观察者通过List进行解耦

        二来,泛型不指定具体的实现类,方便后续进行拓展,
        即只要把拓展的观察者实现类去实现观察接口便合格,
        由此可以实现各式各样的观察者;
    • Observer(观察者接口)

      • 定义了update()方法;
        当我们被观察者状态改变的时候,notifyObservers()方法就会被调用;
        notifyObservers()内部则会调用本update()方法,
        去通知观察者(Observer)做出相应的处理改变;
    • ConcreteObserver(观察者实现类)
      具体实现了Observer(观察者接口)的update()方法;

简单看一下观察者设计模式的代码

  • Observerable接口:
package com.example.jiajiemu.a11.observe;



/**
 * Created by Mjj on 2017/10/6.
 */

public interface Observerable {
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObservers();
}
  • Observer接口:
package com.example.jiajiemu.a11.observe;

/**
 * Created by Mjj on 2017/10/6.
 */

public interface Observer {
    public void update(int edition,float cost);
}
  • ConcreteObserverable实现类:
package com.example.jiajiemu.a11.observe;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Mjj on 2017/10/6.
 */

public class ConcreteObserverable implements Observerable {

    private List<Observer> mObservers;
    private int edition;
    private float cost;

    public ConcreteObserverable() {
        mObservers = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer o) {
        mObservers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        int i = mObservers.indexOf(o);
        if(i >= 0)
            mObservers.remove(i);
    }

    @Override
    public void notifyObservers() {
        for(int i = 0; i < mObservers.size(); i++){
            Observer observer = mObservers.get(i);
            observer.update(edition, cost);
        }
    }

    public void setInfomation(int edition,float cost){
        this.edition = edition;
        this.cost = cost;
        //信息更新完毕,通知所有观察者
        notifyObservers();
    }

}
  • .
    • notifyObservers()
      可以看到方法中所写,遍历所有观察者,
      依次使每一个观察者调用update()方法进行数据更新
      update()方法在ConcreteObserver中具体实现):
    @Override
    public void notifyObservers() {
        for(int i = 0; i < mObservers.size(); i++){
            Observer observer = mObservers.get(i);
            observer.update(edition, cost);
        }
    }
  • ConcreteObserver实现类:
package com.example.jiajiemu.a11.observe;

/**
 * Created by Mjj on 2017/10/6.
 */

public class ConcreateObserver implements Observer {

    private String name;
    private int edition;
    private float cost;

    public ConcreateObserver(String name){
        this.name = name;
    }

    @Override
    public void update(int edition, float cost) {
        this.edition = edition;
        this.cost = cost;
        buy();
    }

    public void buy(){
        System.out.println(name+"购买了第"+edition+"期的杂志,花费了"+cost+"元。");
    }

}
  • .

    • 主要实现,
      update()方法中添加的业务逻辑buy()方法,
      buy()方法是可以根据不同场景做相应的逻辑判断,数据更新;
      或者可以在update()方法中添加更多的业务逻辑
  • Client客户端测试类:

package com.example.jiajiemu.a11.observe;

/**
 * Created by Mjj on 2017/10/6.
 */

public class Client {
    public static void main(String[] args) {
        //创建被观察者
        ConcreteObserverable concreteObserverable = new ConcreteObserverable();

        //创建三个不同的观察者
        Observer observerA = new ConcreateObserver("A");
        Observer observerB = new ConcreateObserver("B");
        Observer observerC = new ConcreateObserver("C");

        //将观察者注册到被观察者中
        concreteObserverable.registerObserver(observerA);
        concreteObserverable.registerObserver(observerB);
        concreteObserverable.registerObserver(observerC);

        //更新被观察者中的数据,当数据更新后,会自动通知所有已注册的观察者
        concreteObserverable.setInfomation(5, 12);
    }

}
  • .
    • setInformation(),封装了一下notifyObservers():
@Override
    public void notifyObservers() {
        for(int i = 0; i < mObservers.size(); i++){
            Observer observer = mObservers.get(i);
            observer.update(edition, cost);
        }
    }

    public void setInfomation(int edition,float cost){
        this.edition = edition;
        this.cost = cost;
        //信息更新完毕,通知所有观察者
        notifyObservers();
    }

传统观察者模式的使用场景

1.一个方面的操作/处理依赖于另一个方面的状态变化
(即观察者的操作依赖于被观察者的状态变化;
埋伏中的警察的操作依赖于小偷的状态变化,
球迷的操作依赖于球赛的状态变化)

  1. 如果在更改一个对象的时候,
    需要同时连带改变其他的对象;

  2. 当一个对象必须通知其他的对象,
    但是你又希望这个对象和其他被通知的对象是松散耦合的;






参考自 慕课网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容