作者 点先生 日期 2018.10.26

安利

我如何零基础转行成为一个自信的前端
虽然我只是个做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? = nullfun getState(): String? { return subjectState}fun ChangeState(subjectState : String){this.subjectState = subjectStatenotifyObservers()}
}
复制代码

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


class ConcreteObserver : Observer {private var observerState: String? = nulloverride 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。

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

诶~

  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,年轻小伙竟作出这种事!

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

  1. 血气方刚的年轻小伙竟去做家政小哥,是怎样成功逆袭转行的

    生活是一个不断遭受挫折和实现自我价值的过程. 这一点是我毕业之后所感悟的. 众所周知,青春总是带有许多美好的回忆,而青春的回忆更多的以校园画面为主,当我们踏入社会后,不仅身份从学生变为职场人,同样的, ...

  2. 年轻小伙竟用python爬取B站视频评论!

    大家好,我是啃书君. 今天为大家带来的小demo是爬取B站视频的评论.开始还以为很难,等正真上手的时候发现,也就是那么回事. 高考对于每个人来说都是人生的重大转折点,你考上一所什么样的大学,极大可能改 ...

  3. 别再说难了,年轻小伙教你如何爬取“新一线城市”二手房信息

    别再说难了,年轻小伙教你如何爬取"新一线城市"二手房信息 主页面信息爬取 主页面分析 主页面url获取 获取页面数据 页面数据解析及保存 详情页 url 数据 详情页信息爬取 详情 ...

  4. 干货!学习笔译需要坚持的几件事

    干货!学习笔译需要坚持的几件事 对于每个学习笔译的小伙伴来说,或许都经历过这样的迷茫: 辛苦练习没效果? 翻译理论一脸懵? 翻译技巧无头绪? 2020CATTI的考试时间已经尘埃落定,上下半年的两场考 ...

  5. 【BX学习之Google+】 谷歌那点事

    █ [BX学习之Google+] 谷歌那点事 █ 系列文章目录 提示:这里是收集了无法归类的相关文章 [BX学习之生活问题] 福建工商-个体户-工商年报-登录方式 [BX学习之生活健康]你的年纪每天睡 ...

  6. 这家研究院太年轻,竟跟世界级选手“叫板”

    金磊 发自 宇宙中心 量子位 报道 | 公众号 QbitAI 一家AI研究院的"打开方式",是这样的: 支持学者发表国际顶会顶刊论文 8个月打造当时全球最大的超大规模智能模型&qu ...

  7. 年轻小伙依靠刺绣增收致富

    在大家的印象中,针线活都是女孩子擅长的事,但是在哈巴河县齐巴尔乡阔斯阿热勒村有一个小伙子依靠刺绣增收致富. 笔者来到杜拉提汉的家中,首先引入眼帘的是他家中摆放的各种作品,他绣的一幅幅作品栩栩如生,有玫 ...

  8. 接地气的O2O模式 杭州两个年轻小伙月销水果8万元

    这几天,一个卖煎饼阿姨的O2O(即online to offline,将线下商务的机会与互联网结合在一起,让互联网成为线下交易的前台)真实案例,成为网络热传的故事-- 一位网友说,"前些天回 ...

  9. C#基础知识学习之 ✨ “精神小伙“——委托(delegate) 的含义和用法

    C#委托(Delegate) 在C#的学习过程中,自然有我们的精神小伙--委托 的一席之地 本文就介绍一下C#中的委托,这位可以包含同类方法函数的小伙子 C# 中的委托(Delegate)类似于 C ...

最新文章

  1. Go 编译的可执行文件是否有动态库链接?
  2. 微信小程序 侧滑效果实现
  3. 分布式架构:并发重复请求和幂等场景技术实现总结
  4. esxi所连交换机划vlan导致vm不能通讯
  5. socket 大端 小端 转换 (转)《二》
  6. 如何控制订单发料后不能删除组件
  7. declare sql语句_每天10分钟学习T-SQL语言基础(Part 5)
  8. mysql记录相互关系查询_MySQL关系表查询两个表的数据
  9. 嵌入式系统分类及其应用场景_词嵌入及其应用简介
  10. python实现文件传输_Python使用socket实现简单的文件传输并校验
  11. ES6 Promise - 让我们解开的面纱(遵循Promise/A+规范)
  12. android c++ http,开源一个C++实现的简单HTTP协议处理库
  13. [高光谱] Hyperspectral-Classification Pytorch 数据集的读取、划分、加载
  14. bat复制文件到指定目录同名_利用bat让文件在指定时间自动进行备份
  15. struts1.x 升级到struts2的几点问题
  16. word加了脚注,分节符(连续)后的内容,跳到下一页
  17. 学习单片机c51矩阵键盘,按键无反应
  18. 麦乐积分:积分兑换系统对于积分运营的重要性
  19. Aspose.Slides使用教程:使用 C# 在 PowerPoint 演示文稿中添加页眉和页脚
  20. 如何用全国天气预报API接口进行快速开发

热门文章

  1. HTML表格的简单使用1
  2. 为什么要上大四???why
  3. WCF中配置文件解析
  4. 第十二章 非对称加密算法-RSA
  5. ClippingNode实现新手引导高亮裁切
  6. USACO SEC.1.3 No.3 Calf Flac
  7. 在整个数据库搜索某个字符串在哪个表的哪个字段中
  8. 【python】类属性以及实例属性、实例方法的介绍
  9. 注解-@Conditional的使用
  10. Servlet Session 跟踪