android 广播观察者,androidObservable观察者模式

android Observable观察者模式

参考:

OBSERVABLE详解

Android开发学习之路--RxAndroid之初体验

在介绍 Observable

之前,我们要先了解两个设计模式:

Observer Pattern - (观察者模式)

Iterator Pattern - (迭代器模式)

这两个模式是 Observable

的基础,

———————————

下面我们先来介绍一下 Observer Pattern

观察者模式

观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。

我们可以使用日常生活中,期刊订阅的例子来形象地解释一下上面的概念。期刊订阅包含两个主要的角色:期刊出版方和订阅者,他们之间的关系如下:

期刊出版方 -

负责期刊的出版和发行工作

订阅者 -

只需执行订阅操作,新版的期刊发布后,就会主动收到通知,如果取消订阅,以后就不会再收到通知

在观察者模式中也有两个主要角色:Subject

(主题) 和 Observer

(观察者)

。它们分别对应例子中的期刊出版方和订阅者。接下来我们来看张图,从而加深对上面概念的理解。

观察者模式优缺点

观察者模式的优点:

支持简单的广播通信,自动通知所有已经订阅过的对象

目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用

观察者模式的缺点:

如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间

如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃

观察者模式的应用

在前端领域,观察者模式被广泛地使用。最常见的例子就是为 DOM 对象添加事件监听,具体示例如下:

确认

function clickHandler(event) {

console.log('用户已点击确认按钮!');

}

document.getElementByIdx_x("btn").addEventListener('click',

clickHandler);

上面代码中,我们通过 addEventListener API

监听 button 对象上的点击事件,当用户点击按钮时,会自动执行我们的 clickHandler函数。

观察者模式实战

Subject 类定义:

class Subject {

constructor() {

this.observerCollection = [];

}

registerObserver(observer) {

this.observerCollection.push(observer);

}

unregisterObserver(observer) {

let index =

this.observerCollection.indexOf(observer);

if(index >= 0)

this.observerCollection.splice(index, 1);

}

notifyObservers() {

this.observerCollection.forEach((observer)=>observer.notify());

}

}

Observer 类定义:

class Observer {

constructor(name) {

this.name = name;

}

notify() {

console.log(`${this.name} has been notified.`);

}

}

使用示例:

let subject = new Subject(); // 创建主题对象

let observer1 = new Observer('semlinker'); //

创建观察者A - 'semlinker'

let observer2 = new Observer('lolo'); // 创建观察者B - 'lolo'

subject.registerObserver(observer1); // 注册观察者A

subject.registerObserver(observer2); // 注册观察者B

subject.notifyObservers(); // 通知观察者

subject.unregisterObserver(observer1); //

移除观察者A

subject.notifyObservers(); // 验证是否成功移除

以上代码成功运行后控制台的输出结果:

semlinker has been notified. # 输出一次

2(unknown) lolo has been notified. # 输出两次

需要注意的是,在观察者模式中,通常情况下调用注册观察者后,会返回一个函数,用于移除监听,有兴趣的读者,可以自己尝试一下。(备注:在

Angular 1.x 中调用 $scope.$on() 方法后,就会返回一个函数,用于移除监听)

———————————

ITERATOR PATTERN

迭代器模式定义

迭代器(Iterator)模式,又叫做游标(Cursor)模式。它提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。

迭代器模式的优缺点

迭代器模式的优点:

简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标取得,但用户需要在对集合了解的前提下,自行遍历对象,但是对于

hash

表来说,用户遍历起来就比较麻烦。而引入迭代器方法后,用户用起来就简单的多了。

封装性良好,用户只需要得到迭代器就可以遍历,而不用去关心遍历算法。

迭代器模式的缺点:

遍历过程是一个单向且不可逆的遍历

ECMAScript 迭代器

在 ECMAScript

中 Iterator 最早其实是要采用类似 Python 的

Iterator 规范,就是 Iterator

在没有元素之后,执行next会直接抛出错误;但后来经过一段时间讨论后,决定采更

functional 的做法,改成在取得最后一个元素之后执行next永远都回传{

done: true, value: undefined }

一个迭代器对象 ,知道如何每次访问集合中的一项, 并记录它的当前在序列中所在的位置。在

JavaScript 中迭代器是一个对象,它提供了一个 next() 方法,返回序列中的下一项。这个方法返回包含done和value两个属性的对象。对象的取值如下:

在最后一个元素前:{ done: false,

value: elementValue }

在最后一个元素后:{ done: true,

value: undefined }

ES 5 迭代器

接下来我们来创建一个 makeIterator

函数,该函数的参数类型是数组,当调用该函数后,返回一个包含 next() 方法的

Iterator 对象, 其中 next() 方法是用来获取容器对象中下一个元素。具体示例如下:

function makeIterator(array){

var nextIndex = 0;

return {

next: function(){

return nextIndex < array.length ?

{value: array[nextIndex++], done: false} :

{done: true};

}

}

}

一旦初始化, next()

方法可以用来依次访问可迭代对象中的元素:

var it = makeIterator(['yo', 'ya']);

console.log(it.next().value); // 'yo'

console.log(it.next().value); // 'ya'

console.log(it.next().done); // true

ES 6 迭代器

在 ES 6 中我们可以通过Symbol.iterator来创建可迭代对象的内部迭代器,具体示例如下:

let arr = ['a', 'b', 'c'];

let iter = arr[Symbol.iterator]();

调用next()方法来获取数组中的元素:

> iter.next()

{ value: 'a', done: false }

> iter.next()

{ value: 'b', done: false }

> iter.next()

{ value: 'c', done: false }

> iter.next()

{ value: undefined, done: true }

ES 6 中可迭代的对象:

Arrays

Strings

Maps

Sets

DOM data structures (work in progress)

RxJS

是基于观察者模式和迭代器模式以函数式编程思维来实现的。RxJS

中含有两个基本概念:Observables 与 Observer。Observables

作为被观察者,是一个值或事件的流集合;而 Observer 则作为观察者,根据

Observables 进行处理。

Observables 与 Observer

之间的订阅发布关系(观察者模式)

如下:

订阅:Observer

通过 Observable 提供的

subscribe() 方法订阅 Observable。

发布:Observable

通过回调 next 方法向

Observer 发布事件。

自定义

OBSERVABLE

如果你想真正了解 Observable,最好的方式就是自己写一个。

其实 Observable

就是一个函数,它接受一个Observer作为参数然后返回另一个函数。

它的基本特征:

是一个函数

接受一个 Observer 对象

(包含 next、error、complete 方法的对象) 作为参数

返回一个unsubscribe函数,用于取消订阅

它的作用:

作为生产者与观察者之间的桥梁,并返回一种方法来解除生产者与观察者之间的联系,其中观察者用于处理时间序列上数据流。

接下来我们来看一下 Observable

的基础实现:

DataSource - 数据源

class DataSource {

constructor()

{

let i = 0;

this._id = setInterval(() =>

this.emit(i++), 200); // 创建定时器

}

emit(n) {

const limit = 10; // 设置数据上限值

if (this.ondata) {

this.ondata(n);

}

if (n === limit) {

if (this.oncomplete) {

this.oncomplete();

}

this.destroy();

}

}

destroy() { //

清除定时器

clearInterval(this._id);

}

}

myObservable

function myObservable(observer) {

let datasource = new DataSource(); //

创建数据源

datasource.ondata = (e) =>

observer.next(e); // 处理数据流

datasource.onerror = (err) =>

observer.error(err); // 处理异常

datasource.oncomplete = () =>

observer.complete(); // 处理数据流终止

return () => { // 返回一个函数用于,销毁数据源

datasource.destroy();

};

}

使用示例:

const unsub = myObservable({

next(x) {

console.log(x); },

error(err) {

console.error(err); },

complete() {

console.log('done')}

});

// setTimeout(unsub, 500);

下面的都是js脚本的代码示例

略。。。

Rx基本使用入门

//创建一个被观察者(发布者)

Observable observable

= Observable.create(new Observable.OnSubscribe() {

@Override

public void call(Subscriber

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值