我如何零基础转行成为一个自信的前端
虽然我只是个做app的,里面很多东西看了没多大用,但我主要学习的是别人的习惯。我现在空闲时间算比较多的,平时想学一些东西的时候,却总是被(自己)打扰。后来就用了里面提到的番茄时间,只需要自己克制一下不在规定时间内看别的东西,学习起来还是蛮有效率的。里面其他的东西,你们也可以看看。
我还能怎样啊,就是学习了一下观察者模式,再看了点源码,再去学习rxjava1.0,再看2.0,这样一套流程下来,看的是行云流水,思路不卡壳。
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。
我们会把多个依赖者称为 观察者(订阅者/Observer) ,一个被依赖者称为 主题(目标/Subject)
订阅报纸,这个例子我不讲,太多人讲了,没意思。
要玩就玩个骚的,比如……
我不讲。
出版者 + 订阅者 = 观察者模式
这样一句话相信大家就比较明白了,无论是讲过无数次的订阅报纸问题,还是订阅什么东西,只要是当对象改变状态需通知订阅者知道的模式,就叫做观察者模式(印象中也被叫做观察者模式)。根本不用管每个订阅者是否要更新还是啥都不做,只要通知到位了,就行。
要手撸代码,我们还是先理清一下思绪,看看要做什么。
既然所有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值改变。
观察者模式根据推送消息时的不同,又分为**“推模型” 和 “拉模式”。**
拉模式:
在上面写的demo中,我们在Subject类中更新数据时,observer.update(this)。
这个this传递的就是concreteSubject实体对象。因为concreteObserver获得了concreteSubject对象,所以需要什么信息时,直接从对象中拉去数据就行了。
这种主题对象在通知观察者时,直接传含有信息的对象的模式,叫做拉模型
//拉模型 observer.update(this) 复制代码
推模式:
拉模型传递的一个对象,里面包含了许多信息,而推模型,就是将对象里面的具体信息,传递进去。
这种主题对象在通知观察者时,传递观察者需要的具体信息的模式,叫做推模型。
//推模型 observer.update((this as ConcreteSubject).getState()) 复制代码
注意,用推模型的时候,接口参数跟拉模型是不一样的。
安全性:
拉模式是比较安全的方式,因为只会给订阅者提供规定的信息。
而推模型相对来说会比较不安全,因为观察者获取的是一个包含了许多信息的对象,但是它可能不需要这么多信息,那多余的信息,就是一个安全隐患。但这样的情况发生时,我建议是提供一些get方法,方便获取不同的数据。
Java API有内置的观察者模式,为什么我们还要自己写呢?
问得好! 稍后就讲!
Java.util.Observer 和 Java.util.Observable 分别对应着我们写的Observer 和 Subject。
这里update里面的两个变量,第一个变量是主题本身,目的是为了让观察者知道是哪一个主题通知它的。第二个变量是传入notifyObservser()的数据对象。
诶~
现在来解决刚刚提的问题,为什么我们要自己写个观察者模式呢?
因为Java.util.Observable这玩意儿特么的不是接口,是个类啊! 如果我们要设计一个类想同时拥有Observable和另一个超类的行为的话,就根本没办法做,谁叫java不支持多重继承呢。这点限制了Observable的复用能力。而复用正是我们使用设计模式的动机!
关于change
先来看关于change的几个方法。
嗯~
懂了。这三个方法就更改/获取change的值而已。在哪里用到了呢?
整个类中,只有notifyObservers(Object arg)中调用了这样一段代码。
哦!!!!!!!!!!明白了。
也就是说,如果调用notifyObservers()前没有调用setChanged(),观察者就不会被通知。 这样有啥子好处呢?
能灵活处理通知与否!数据可能每秒都在更新,但是观察者却不需要更新这么频繁,就可以每隔一段时间,再调用一下setChange(),获取一次数据。
反向思考一波,也就是说,在使用内置的Observable时,在想让观察者被通知之前,一定要先执行setChange()!
写这篇文章本意是学习一下观察者模式,但始终想不出来比较好(sao)的题目,于是才做了一次标题党,也不知道UC会不会叫我去上班。
下个月开始,我不会再一直写设计模式相关的东西。公司拖欠工资,即便是年底,我也要学点其他东西,准备一下面试。但是 如果有人喜欢我这种画风的文章和rxjava相关的东西的话,我会把《为了学习Rxjava,年轻小伙竟作出这种事!(2)》写出来 。
以下是我“设计模式系列”文章,欢迎大家关注留言投币丢香蕉。
也可以进群跟大神们讨论。qq群:557247785