为了学习Rxjava,年轻小伙竟作出这种事!

作者已经搬迁去隔壁网站,也欢迎大家关注我们的写作团队:天星技术团队

安利

我如何零基础转行成为一个自信的前端
虽然我只是个做app的,里面很多东西看了没多大用,但我主要学习的是别人的习惯。我现在空闲时间算比较多的,平时想学一些东西的时候,却总是被(自己)打扰。后来就用了里面提到的番茄时间,只需要自己克制一下不在规定时间内看别的东西,学习起来还是蛮有效率的。里面其他的东西,你们也可以看看。

初识观察者模式

我还能怎样啊,就是学习了一下观察者模式,再看了点源码,再去学习rxjava1.0再看2.0,这样一套流程下来,看的是行云流水,思路不卡壳。

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。

我们会把多个依赖者称为观察者(订阅者/Observer),一个被依赖者称为主题(目标/Subject)

订阅报纸,这个例子我不讲,太多人讲了,没意思。
要玩就玩个骚的,比如我不讲。

出版者 + 订阅者 = 观察者模式

这样一句话相信大家就比较明白了,无论是讲过无数次的订阅报纸问题,还是订阅什么东西,只要是当对象改变状态需通知订阅者知道的模式,就叫做观察者模式(印象中也被叫做观察者模式)。根本不用管每个订阅者是否要更新还是啥都不做,只要通知到位了,就行。

手撸观察者模式

要手撸代码,我们还是先理清一下思绪,看看要做什么。

  1. 有一个Subject,还有一个Observer
  2. Subject需要存储所有订阅了的Observer,所以Subject有一个Observer集合,和添加/删除方法
  3. Subject需要通知所有订阅的Observer更新数据,所以所有Observer都有一个可被Subject调用的数据更新的方法
  4. 没有了,已经满足甲方的需求了。开撸吧!

桥豆麻袋!!!!!!!!!!!

既然所有Observer都有至少一个更新方法的话,我们就提炼出一个父类出来。而Subject那边,我们也提一个吧。项目里可能不止一个需要被监控的目标。
我可真是个小机灵鬼儿!!!!
一张图说明上面的内容。

开撸!!!!

interface Subject {
    var observers: ArrayList<Observer>
        get() = ArrayList<Observer>()
        set(value) = TODO()

    fun registerObserver(observer: Observer) {//注册观察者
        observers.add(observer)
    }
    fun removeObserver(observer: Observer) {//删除观察者
        observers.remove(observer)
    }
    fun notifyObservers() {//更新
        for (observer in observers) {
            observer.update(this)//通知观察者更新
        }
    }
}
interface Observer {
    fun update(subject: Subject)//有这一个方法就够了
}

在具体主题中,我们需要有一个状态改变,来导致通知所有订阅者更新的方法。

class ConcreteSubject : Subject {
    private var subjectState: String? = null

    fun getState(): String? { 
        return subjectState
    }
    fun ChangeState(subjectState : String){
        this.subjectState = subjectState
        notifyObservers()
    }
}

具体观察者中,同步一下代表收到消息就好了。在实际开发中在update()里面做自己想做的事就好了。


class ConcreteObserver : Observer {
    private var observerState: String? = null

    override fun update(subject: Subject) {
        observerState = (subject as ConcreteSubject).getState()
    }
}

在客户端调用的时候,先注册,再执行changeState(),就能把当前已经注册的对象的observerState值改变。

“推”与“拉”

观察者模式根据推送消息时的不同,又分为“推模型”“拉模式”。

  1. 拉模式
    在上面写的demo中,我们在Subject类中更新数据时,observer.update(this)。
    这个this传递的就是concreteSubject实体对象。因为concreteObserver获得了concreteSubject对象,所以需要什么信息时,直接从对象中拉去数据就行了。
    这种主题对象在通知观察者时,直接传含有信息的对象的模式,叫做拉模型
//拉模型
observer.update(this)
  1. 推模式
    拉模型传递的一个对象,里面包含了许多信息,而推模型,就是将对象里面的具体信息,传递进去。这种主题对象在通知观察者时,传递观察者需要的具体信息的模式,叫做推模型。
//推模型
observer.update((this as ConcreteSubject).getState())

注意,用推模型的时候,接口参数跟拉模型是不一样的。

  1. 安全性
    拉模式是比较安全的方式,因为只会给订阅者提供规定的信息。
    而推模型相对来说会比较不安全,因为观察者获取的是一个包含了许多信息的对象,但是它可能不需要这么多信息,那多余的信息,就是一个安全隐患。但这样的情况发生时,我建议是提供一些get方法,方便获取不同的数据。

Java.util.Observer & Java.util.Observable

Java API有内置的观察者模式,为什么我们还要自己写呢?
问得好! 稍后就讲!
Java.util.Observer 和 Java.util.Observable 分别对应着我们写的Observer 和 Subject。

Java.util.Observer

这里update里面的两个变量,第一个变量是主题本身,目的是为了让观察者知道是哪一个主题通知它的。第二个变量是传入notifyObservser()的数据对象。

Java.util.Observable

诶~

  1. 我们刚刚是把Subject写成interface,这里是写的class。
  2. 我们用的ArrayList存储Observer,它用的是Vector来存储。
  3. 在添加/删除Observer上,它是写的addObserver(),deleteObserver()。
  4. 它有notifyObservers() 和 notifyObservers(Object arg),来调用Observer的update方法。
  5. 多了一个布尔值属性changed

现在来解决刚刚提的问题,为什么我们要自己写个观察者模式呢?
因为Java.util.Observable这玩意儿特么的不是接口,是个类啊!
如果我们要设计一个类想同时拥有Observable和另一个超类的行为的话,就根本没办法做,谁叫java不支持多重继承呢。这点限制了Observable的复用能力。而复用正是我们使用设计模式的动机!

关于change
先来看关于change的几个方法。

嗯~
懂了。这三个方法就更改/获取change的值而已。在哪里用到了呢?
整个类中,只有notifyObservers(Object arg)中调用了这样一段代码。

哦!!!!!!!!!!明白了。
也就是说,如果调用notifyObservers()前没有调用setChanged(),观察者就不会被通知。
这样有啥子好处呢?
能灵活处理通知与否!数据可能每秒都在更新,但是观察者却不需要更新这么频繁,就可以每隔一段时间,再调用一下setChange(),获取一次数据。

反向思考一波,也就是说,在使用内置的Observable时,在想让观察者被通知之前,一定要先执行setChange()!

还有一些东西

  • 在定义中,我们说到观察者模式是一对多的依赖。一是主题,多是观察者,依赖是观察者对主题的单向依赖。观察者不能主动获取主题的信息,只能等主题通知更新。
  • 主题通知观察者更新的时候,顺序是不确定的。 多个观察者之间收到信息的顺序是不确定的,别在此处想做什么骚操作。
  • 当一个订阅者订阅了多个主题时,为了区别是哪个主题发来的消息,一般有两种处理方式。1. 订阅者拥有多个更新方法,每个主题调用不同的更新方法。2. update()接收到消息后先判断是哪个主题发来的消息(参考Java.util.Observer)。
  • 观察者模式的优点:实现了观察者和目标之间的抽象耦合; 实现了动态联动;
  • 观察者模式的缺点:由于主题通知的是所有注册过的订阅者,万一某一条数据某一个订阅者不需要更新,可能会引起数据的误更新,就麻烦了。

最后

写这篇文章本意是学习一下观察者模式,但始终想不出来比较好(sao)的题目,于是才做了一次标题党,也不知道UC会不会叫我去上班。
下个月开始,我不会再一直写设计模式相关的东西。公司拖欠工资,即便是年底,我也要学点其他东西,准备一下面试。但是如果有人喜欢我这种画风的文章和rxjava相关的东西的话,我会把《为了学习Rxjava,年轻小伙竟作出这种事!(2)》写出来

以下是我“设计模式系列”文章,欢迎大家关注留言投币丢香蕉。
也可以进群跟大神们讨论。qq群:557247785

设计模式入门
Java与Kotlin的单例模式
Kotlin的装饰者模式与源码扩展
由浅到深了解工厂模式
为了学习Rxjava,年轻小伙竟作出这种事!

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

推荐阅读更多精彩内容

  • 今天,晴,周一。 2018年8月27日。一早就忙碌开来,不知怎么分辨这忙是为什么? 吃穿住行,一样少不得,不管好孬...
    雾里看花_c7e4阅读 230评论 2 6
  • 在海的尽头, 有沙滩 ,有贝壳。 还有海浪。 可是,人们并不知道, 污染海水,会造成多大的变化。 海水里的鱼儿们,...
    茹果_55e7阅读 261评论 0 0
  • 感觉自己陷在坑里,拼命挣扎,结果却是越陷越深。 知道问题出在哪里,却好像对它无能为力。这真是一件很让人感到绝望的事...
    似水流年_8b7d阅读 114评论 0 0
  • 33男扮女装 天色已朦朦胧胧,大街上人也都各自回家生火做饭,相夫教子。 空荡荡的大街上,楚风三人骑马慢慢前行。 ...
    犁地成佛阅读 719评论 0 51