美文网首页RxJavaAndroid知识Android开发
RxJava+Retrofit (二) 观察者模式及Rx基础概念

RxJava+Retrofit (二) 观察者模式及Rx基础概念

作者: Van96 | 来源:发表于2017-03-19 13:28 被阅读539次

本系列的七篇文章(目前完成进度:2/7):
1、什么响应式编程
2、观察者模式及Rx基础概念解释
3、RxJava深入浅出
4、RxJava+Retrofit 的结合
5、RxJava的高阶使用
6、Retrofit的进阶应用
7、总结

观察者模式

其实非常简单,就是监听。我们在做Android开发的时候,必定绕不过的就是给Button设置监听器(你没做过算我输好吧):

 bn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("TAG","OnCLick");
            }
        });

在上面的例子中,匿名内部类View.OnClickListener就是观察者,按钮bn就是被观察者。一旦被观察者被观察到“被点击”这个事件,观察者就会做出相应的反应(出log)。
 

 
  
  是的,你已经用了很久的观察者模式了,只是你不知道而已。
  观察者模式的描述应该是这样的:定义一个被观察对象,再定义一个(或多个)观察者,观察者时刻在观察着被观察对象的一举一动,一旦被观察对象的状态发生了变化,所有的观察者都会马上做出反应。
  
  
  补充一点,在现实的编程中不会有“时刻都在观察”这种这么蠢的实现方式的,所以最好不要将观察者模式理解为'观察者'时刻监控着'被观察者'(虽然语义上这样的),应该理解为:'被观察者'其实是‘通知者’,自己有点什么状态变化(或者是什么事情发生)就马上通知"观察者"(就是实现约定好的),然后观察者再对此做出反应。(所以我个人更倾向于将“观察者模式”称为“通知者模式”)
  
  
  
  回到本系列的第一篇,那个和全蛋一起工作的你。流水线模式是观察者模式吗,是吗?是的。但是,请注意,只有最后的打包员才是观察者!!!你们这些加工工人并不算是观察者,就算是观察者,地位也是比打包员的低的!(此处我是后来才意识到的,因而算是一个错误)
  为什么这样说,其实大家可以理解为打包员才是可以睡懒觉的人,当然在加工工人没事做的时候也是在睡懒觉。但是,就算你们都是在睡懒觉,打包员才是“观察者”,当手机开始在流水线上流动的时候,流水线只会通知打包员,打包员一醒,就会把你们这些加工工人全部叫醒,帮他干活。(需要感受一下打包员和加工工人地位的差距,以及唤醒的时机)
  
  现在再理一下思路:
  • 流水线是“被观察者”,
  • 流动着的手机是“数据流”,
  • 打包员是“观察者”,
  • 观察的事件是“手机毛坯进入流水线”,
  • 观察者的响应动作是“将没有问题的手机打包好,有问题的手机另行处理”,
  • 订阅是“事件发生以后响铃通知”。
  • 至于加工工人,只是在观察者的响应动作发生前对数据流的处理。
      
      
    (Ps,将“被观察者”换为“通知者”真的是会舒服很多)

用RxJava做个小Demo

例子还是我们的手机加工,废话不多说,直接上代码:

static void product() {
        Phone[] phones = new Phone[5];
        for (int i = 0; i < phones.length; i++) {
            phones[i] = new Phone(i + "号iPhone");
        }

        Observable.from(phones)                             //Observable,被观察者
                .map(new Func1<Phone, Phone>() {            //装天线加工
                    @Override
                    public Phone call(Phone phone) {
                        try {
                            Thread.sleep(2000);  
                            //为了体现顺序,我给加工设置了耗时
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        return phone.change("装了天线的");
                    }
                })
                .map(new Func1<Phone, Phone>() {            //装摄像头加工
                    @Override
                    public Phone call(Phone phone) {
                        return phone.change("装了摄像头的、");
                    }
                })
                .subscribe(new Observer<Phone>() {          //Observer,观察者订阅事件
                    @Override
                    public void onCompleted() {
                        System.out.println("搞掂,收工!");
                    }

                    @Override
                    public void onError(Throwable e) {
                        System.out.println("出了点小问题");
                    }

                    @Override
                    public void onNext(Phone phone) {
                        System.out.println(phone.show()+"被打包好了");
                    }
                });
    }

输出结果是:

装了摄像头的、装了天线的0号iPhone被打包好了
装了摄像头的、装了天线的1号iPhone被打包好了
装了摄像头的、装了天线的2号iPhone被打包好了
装了摄像头的、装了天线的3号iPhone被打包好了
装了摄像头的、装了天线的4号iPhone被打包好了
搞掂,收工!

Process finished with exit code 0

//附,这里的输出是每两秒输出一次

代码我放到Gist了,赏脸给个star可好.

RxJava的基本概念

Observable:被观察者,也可解释为发射源,或数据流就是从这里发射出来的;

Observer:观察者,接收源,数据流就是在这里被接收;

Subscriber:“订阅者”,也是接收源,那它跟Observer有什么区别呢?Subscriber实现了Observer接口,比Observer多了一个最重要的方法unsubscribe( ),用来取消订阅,当你不再想接收数据了,可以调用unsubscribe( )方法停止接收,Observer 在 subscribe() 过程中,最终也会被转换成 Subscriber 对象,一般情况下,建议使用Subscriber作为接收源;

Subscription:Observable调用subscribe( )方法返回的对象,同样有unsubscribe( )方法,可以用来取消订阅事件;

Action0:RxJava中的一个接口,它只有一个无参call()方法,且无返回值,同样还有Action1,Action2...Action9等,Action1封装了含有 1 个参的call()方法,即call(T t),Action2封装了含有 2 个参数的call方法,即call(T1 t1,T2 t2),以此类推;

Func0:与Action0非常相似,也有call()方法,但是它是有返回值的,同样也有Func0、Func1...Func9;

关于Action 和 Func:

先说Func吧,在上面的demo中,我们用到了Func1,于是我们去看看Func1的源码:

/**
 * Represents a function with one argument.
 */
public interface Func1<T, R> extends Function {
    R call(T t);
}

非常短吧,只有一个方法call(T t),再跑去看看Func2的源码:

/**
 * Represents a function with two arguments.
 */
public interface Func2<T1, T2, R> extends Function {
    R call(T1 t1, T2 t2);
}

同样的,也是只有一个方法,call(T1 t1,T2 t2)。
再看回我们的Demo:

 .map(new Func1<Phone, Phone>() {            //装摄像头加工
                    @Override
                    public Phone call(Phone phone) {
                        return phone.change("装了摄像头的、");
                    }
                })

在这里,我们想要做的是“给手机装摄像头”,我们的预期是我们提供一个方法给你,你只需要把“还没装摄像头的手机”当作是一个参数输入到这个方法里面,然后这个方法就会返回“装了摄像头的手机”。 (很明显,这段话的“你”指的是Rx框架)
  然而,在Java中是没有方法指针这种东西,为了达到“将指定方法传递给Rx框架”的目的,设计者设计了Func和Action。
  我们通过传递Func实例来传递一个方法!首先我们先新建一个Func1实例,然后将我们想要执行的方法写到Func1实例中的call方法中(覆盖),最后再把这个实例传递给Rx框架。Rx框架就会在指定的时刻执行我们Func1实例中的call方法,并把call方法的返回值传递到下一个流程。
  
  大概就是这样了,通过传递实例来传递方法在Java中其实不少见,最常见的就是给Button传递一个OnClickListener来传递回调方法。
  此外,我们在使用Func有时可能不止需要一个输入,可能要0个输入就好了,但有时需要可能需要2个、3个...输入的话,那该如何。
  诸君莫方,我们还有Func0、Func1、Func2...肯定有一款适合你。Func后面的数字表示的是call方法的参数个数,我们只要根据需要选择Func接口就可以了(可看上面的两个Func接口的源码,比较出差别)。
  
  
  说完Func,Action也就差不多了,Action和Func的区别就在于,Action没有返回值。

最后

似乎也没有什么好总结的了,就这样了吧。


Reference:http://www.jianshu.com/p/5e93c9101dc5

未经授权,禁止转载
原文地址:http://www.jianshu.com/p/b1bd50afb071

相关文章

  • RxJava+Retrofit (二) 观察者模式及Rx基础概念

    本系列的七篇文章(目前完成进度:2/7):1、什么响应式编程 2、观察者模式及Rx基础概念解释3、RxJava深...

  • RxJava+Retrofit (一) 什么是响应式编程

    本系列的七篇文章(目前完成进度:2/7):1、响应式编程2、观察者模式及Rx基础概念解释 3、RxJava深入浅...

  • Rxjava 认识1

    /** 1 概念: Rxjava 基于观察者的 异步 事件库* 2 rx的观察者模式 Observer...

  • RxSwift文档(中文翻译上)

    Geting Started 基础部分 RxSwift文档传送门 观察者模式和正常序列的等价性是理解Rx的最重要的...

  • rxjava笔记(1)

    rxjava的基础概念 观察者模式于发布-订阅模型rxjava有四个基础概念 Observable 被观察对象 O...

  • rxjava1基本元素源码分析

    代码示例 常用类说明 被观察者 rx.Observable 订阅 rx.Subscription 观察者 rx.O...

  • Rx异步

    Rx基本流程 RxJava是一个异步框架,基于观察者设计模式,被观察者Observable,通过subscribe...

  • Reactive Extensions 相见恨晚的Rx.Net

    何为Reactive Extensions(Rx) Rx是一个遵循函数式编程的类库,它引用观察者以及迭代器设计模式...

  • 设计模式之 观察者模式

    观察者模式 概述 UML类图 代码栗子 总结 概念 概念 观察者模式又叫做发布-订阅模式,观察者设计模式定义了对象...

  • 第10章 RxJava

    一、基本概念 RxJava的两个关键词:异步、简洁。RxJava的异步实现,是通过一种扩展的观察者模式来实现。Rx...

网友评论

  • cde131ae7ab0:非常好呢,加油,大神:smiley:
  • 2bb84e08d233:希望结合retrofit的文章会有从易到难的栗子,哈哈😄。
  • 2bb84e08d233:看完,感觉很不错。加深了理解,本身就是个菜鸟,坐等更新捧场。😁

本文标题:RxJava+Retrofit (二) 观察者模式及Rx基础概念

本文链接:https://www.haomeiwen.com/subject/ansmnttx.html