前言
最近在学习Rxjava2,虽然在实际的项目中使用也看了很多的文章和文档同时也看了菜鸟窝Ivan老师的免费课程。,学会了如何使用但是忘记的很快,也没有很好的总结,在学习的时做的笔记过了一段时间发现自己做的笔记都有些看不明白,作为小白的我写博客还是有点胆战心惊的,这篇博客的主要的目的是引导没有了解过Rxjava的人一个参考,讲一些简单的原理和常用操作符及使用场景,可能会有错误希望大家多多指教批评,去其糟粕取其精华,那么开始学习之旅吧。
概念
我们知道Rxjva使用的是观察者设计模式,那么什么是观察者模式呢?其实我们在开发中一直使用,只是我们没用认真的去了解,常见按钮点击事件就是一个很好的例子。也许现在你还疑惑那么在我讲解概念之后回头在看你就会明白了。首先我们要先了解几个概念。
- 什么是观察者模式?
观察者(Observer)模式:是对象的行为模式,又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听(Source/Listener)模式或者从属(Dependents)模式。
抽象主题(Subject)角色:
抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
具体主题(ConcreteSubject)角色:
将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
抽象观察者(Observer)角色:
为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
具体观察者(ConcreteObserver)角色:
存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
这是一种比较官方的说法,当然每个人的理解不同。简单来说在观察者模式中,有两个对象观察者(订阅)和被观察者(被订阅),一个被观察者可以有很多观察者,当被观察者法神变化的时候,所有的观察者都会收到通知,从而改变自己(更新自己)。举个例子:一个课堂上,只会有一个老师(被观察者)讲课,当讲到一个知识点,每个都同学(观察者)听到老师所讲的知识点,有的会做笔记有的会提问(相当于所有观察者接到通知改变自己)。这就是观察者模式。
- 是观察者模式图形分析?
抽象主题(Subject)角色:
抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
具体主题(ConcreteSubject)角色:
将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
抽象观察者(Observer)角色:
为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
具体观察者(ConcreteObserver)角色:
存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
从这个关系图我们可以看出左侧是被观察者(Subject/Observable),右侧是观察者(Observer),他们的关系是1-0..*(1对多的关系)。被观察者通过集合管理观察者,并且有三个方法:attach()绑定(add()加入集合) detached()解绑(remove()移除集合) notifiyObeserver()通知所有的观察者(遍历集合调用updata()方法)。
明白了关系图那么我们通过代码来实际运用下加深理解:
/**
* 观察者
*/
public interface Observer {
void upData(String state);
}
首先我们创建一个观察者,他只用一个方法upData(String state);更新状态。我们在创建两个类来继承它。
public class TomObserver implements Observer{
@Override
public void upData(String state) {
/*
* 在这里我们根据接受到state做相应的处理
*/
System.out.println("我是Tom 我在"+state);
}
}
public class JackObserver implements Observer{
@Override
public void upData(String state) {
/*
* 在这里我们根据接受到state做相应的处理
*/
System.out.println("我是Jack 我在"+state);
}
}
在这里我们创建2个观察者子类Tom和Jack。实现upData()并根据介绍到的state做相应的处理,这里我们只是简单的打印接到信息。观察者创建完成我们在创建被观察者(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);
}
}
}
这段代码也很容易理解,就是和上面我们的关系图一样被观察者通过集合管理观察者。通过绑定添加,解绑移除,notifyObservers()通知所有观察者。我们在创建一个他的子类。
public class MessageOberver extends Observable{
public void change(String state){
notifyObservers(state);
}
}
创建子类的,其实它就做了一件事就是调用父类的notifyObservers()方法。
好了。现在所有的准备工作我们已经做好了让我们来实际操作一下,到底是怎么运作的。
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("跑步");
}
}
这段代码我们先创建2个Observer(观察者)实例,再创建MessageOberver(被观察者)通过attach()绑定,当我们被观察者(再创建MessageOberver),状态改变(“打篮球”)看看会发生什么?
绑定观察者JackObserver
绑定观察者TomObserver
我是Jack 我正在打篮球
我是Tom 我正在打篮球
解绑被观察者TomObserver
我是Jack 我正在跑步
可以看到当我们的被观察者状态改变要去打篮球的时候,所有他的观察者(也就是attach()绑定的对象)都能接到信息,当我们解绑的后解绑的观察者就不能在接到信息了。这就是我们的观察者模式。其实这么看来还是挺简单的。
在理解了观察者模式后我们在回到文章开始的时候提到的android中用的观察者模式比如点击事件,放到我们写的例子中我们应该怎么去理解呢?
public class Test {
public static void main(String[] args) {
Observer jObserver=new JackObserver();
Observer tObserver=new TomObserver();
MessageOberver oberver=new MessageOberver();
/*
* oberver相当于Button
* attach相当与setOnclickListener
* jObserver相当于 OnclickListener
* change方法就是我们在监听中对应的要做的事情(这里我们是调用notifyObservers(),
* 它的内部是调用每个oberver的updata方法 我们可以在updata方法中做不同的处理)
*/
oberver.attach(jObserver);
oberver.attach(tObserver);
oberver.change("打篮球");
oberver.detach(tObserver);
oberver.change("跑步");
}
}
看了我的注释在结合平时我们写的代码是不是有一种不约而同的感觉呢。那么在实际开发中我们又在那里用到观察者模式呢?简单的例子。其实在实际项目中我们想让多个界面监听一个对象的状态变化时我们就可以用到观察者模式。比如常见的下载应用我随便找的两个截图
这是我们常见手机应用软件的截图这是两个不同的页面,2个页面下载进度同步,其实我们就可以使用观察者模式,下载任务为被观察者页面(Activity或者Fragment)为观察者(实现接口,参数将String state 该改成DownInfo info下载任务)那么当下载进度改变时我们实时跟新状态,那么两个页面的进度同步啦,比如音乐播放进度等根据业务要求观察者设计模式有时会帮助我们解决不少场景需要。
结语
这篇文章主要是讲解什么观察者模式,虽然本文是Rxjava小白入门,但是讲下观察者模式还是有必要的。虽然网上也有很多讲解,有的讲的太深,有的讲的太多,并不是他们说的不好,而是身为小白的我去读太深的东西让我难以记住和理解,希望这篇文对你有所帮助。下篇文章我会简单讲解下java中的观察者模式和Rxjava的简单使用。