00:00
刚才呢,我们讲了一个普通方案,虽然可以用,但是呢不好。对吧,不好,不好的原因就是刚才我们说的违反了一些这些问题,你刚才看这个代码里面也能看出来,这个很麻烦,不好用怎么办好办,咱们下面呢,就来说一下观察者模式,那观察者模式他是怎么玩的呢?哎,他是这么思考这个问题的。他说哎,你这个观察者不是类似于像订牛奶的业务吗?咱们可以这么考啊,说这边有个牛奶站。牛奶站,牛奶站呢,我们把它认成subject,那么用户呢,就是就是牛奶站呢,它是它是一。而我们用户呢,有很多,诶就跟我们那个气象站一样,对吧,你有很多第三方,但是我的气象局只有一个,那怎么办呢?我是一个被别人观察的,你是观察者。怎么办呢?好,对于沙来说,你可以向我登记移除或通知,所以说我支持你来注册。
01:06
我支持你遗嘱,同时就好像有一个用户他要去订牛奶了,他怎么订牛奶的呢?他先到牛奶的奶奶说,哎,哥们儿,我准备。病牛来了,那么这边的人呢,就给你先把你包起来说哎,这有一个用户了,比如用户是张三。说这个张三呢,将来就是我们的一个用户,等到这边有。到时间了,牛奶到了,那么这边呢,就把这个信息给他推过来就完事了。那么这个用户比如说哪一天说,诶不好意思,我这个不想喝了,那么我再给你发一个消息,说我要我不干了,我移除,移除完了过后呢,我这条线就不再给你推了,多简单一个事儿,其实这种逻辑呢,就特别适合刚才这种就是订阅的模式。这种方式在我们Spark里面也是用的非常多的,而且你将来有大量这种设计设计思想在里面去。
02:01
好了,那现在我们就来搞一把啊。再说一遍啊,这些模式也不是哪一个人提出来的,这些模式呢,他早就在这个我们说的那个升级模式里面有有有有这个观点啊,你们将来这个观察者模式也好,装饰者模式也好,不但是看Java里面造用无误。那么我们来看关键就是这个奶站,就是我们subject,它应该提供什么方法呢?它至少要提供三个方法,一个叫register observe,就是注册,还有一个remove啊,Observe就是这个写错了啊,叫移移出。这个一处。好的,移除就是这个人,他他不想订牛奶了,就就移除嘛。就像我们说的一个互联网新浪,人家订阅了你这个,呃,天气天气的这个通知,肯定我一个月要给你交钱的,一般来讲也不是完全免费,比如将来你们自己做个网站,说我要去看火车站的票有多少张,一般也会给你开接口。
03:03
但是一般可能要付付个费用啊,比如说你跟那个,呃,这个北京西站,我在北京南站,你说我要你接口他们一个月,比如说收你这个。比如说收你1万块钱。啊,我开始收费嘛,像个会员一样,对吧,那我不想用了,我就移除了,我说我我不干了,我就发一个消息,啪一点不干了,那么还有一个呢,Notify observers加个s observers这个地方就说将如果我们这个奶站有变化,或者说我们天气这这个奶站就相当于我们气象局了。气象局这个用户就有点类似于我们的第三方,第三方的这个这个这个公司啊或者网站。啊,那么如果你有天气变化,我就调用notify通知所有的注册用户,因为大家都是会员嘛,不能厚此薄彼,我就通知所有根据不同的需求,可以更新数据,让用户来学,也可以推送,目前呢,我们是相当于直接推送过去了。
04:05
我们相当于直接给你推过去,你就更新了。相当于说目前我们就是直接这个推送给你啊,实时推送,那现在观察者模式的原理我们就讲完了。那讲完原理,下一步呢,必然就到了我们的实这个这个实现阶段啊,啊,还把这个原理还还有还有一个我们刚才分析的是这。就是对于subject来说呢,我们这边会定义一个类似于一个接口,其实在这儿就是里面要有三个方法,谁来实现,具体的这个subject来实现就可以了。另外一个呢,就是同学们看到这个observe observe里面最核心的一个方法就是update。就是这个这个update是给谁用的啊,同学们,这个观察者的update其实是给subject用的。因为我这边信息变化了,我要通知你,我要推送给你,你得给我一个接口啊,你不给我接口我怎么调你啊,就好像天气,呃,天气发生变化了,我我想把这个信息告诉QQ这个腾讯公司,或者告诉新浪,你不给我接口我怎么调,所以说这个呢,是要求所有的接入者。
05:19
必须实现的,就好像你到奶站去订牛奶,你必须告诉我你的地址或者电话号码,我给你打电话对吧?好,道理很简单,那么观察者模式特别适合对象之间的多对一的依赖关系。这种方案被依赖的对象我们称之为subject,依赖的对象就依赖对象称之为observe。观察者subject通知observe的变化,比如这里奶站SUBJECT1的一方用户observe,好,这个原理我就分析完了。好,原理分析完了,原理分析完了过后呢,最后我们把这个设计图给大家画出来,待会儿呢,我要这么写了。
06:00
注意听讲啊。这个地方待会我会设计一个subject,看清楚了。这个沙发是个接口,到我们这边就是一个特质,Tree。啊,因为这个也是用于Java,所以说我这写的是interface,那么到我们这呢,应该写成train啊,Trade就是我们呃这个接口了,然后里面有三个方法必须实现,然后下面这个我data ST,就是state里面我要实现这三个方法。这三个方法其实是给谁用的,你们知道吗?啊,其中这个方法和这个方法是给用户用的,因为你要注册你就调我这个,你要移除就调这个,那么notify是我自己用的。就是我这个weather data data是自己用的好,然后当有一个公告版,我不管这个公版公版是谁啊,你可以向我发出一个注册或者移除的指令。如果是网络,咱们可以加入一个阿卡。啊,如果是网络可以加入阿卡,让他在这不停的得消息吗?啊,我要调你的注册,哎呀,把它关理起来吗?我们那个SPA克不就这个道理吗?
07:06
对不对,好,如果我要移除,我不玩了,我也给你发出一个这个消息,或者是这我就没写网络的啊,我直接调这个方法了,如果是网络你是直接调不了,除非你用后面我们讲的这个远程代理模式。啊,那么这个通知消息呢,是他发出看清楚了啊,两个行为注册移除是。这个接入者发入的,那么一旦我的天气有变化,我就通知所有的用户,好,这就是我们的一个设计方法,好设计方法,那有这个方法过后呢,这个这个地方这个好处啊,再分析完。观察者设计模式后,会以集合的方式来管理用户,就是个我们将来这个哪个地方有个集合呢?就这就这个地方。同学们看到的这个东西,Whether the state ST里面会出现一个集合。
08:02
就是同学们在这个地方会有个集合,当然这个集合用什么,待会儿我们再说,这有个集合,这个集合是谁呢?就是谁要来,我就把它扔到这个集合里面管理。扔到集合房里面,好,这是集合,那么呃,有了集合过后,包括注册遗嘱通知,这样我们增加观察者就可以理解成增加一个新的公告板,而不需要去修改核心内容,因为你来一个我就动态的加进去,来一个就动态的加进去我的代码。我这个Y热带塔不会再做任何修改了,就不会修改了。不会修改代码。好,这是整个这个流程分析,我给同学们板书一下,下面呢,板书完了我们就写代码了。好,刚才我们做了一个分析,就是关于观察者模式的整个这个分析的一个流程,好,那么我讲了什么东西呢?我讲了观察者模式的一个原理。
09:04
好朋友们。啊,朋友们,这是观察者模式的一个原理,还是很重要的,那我讲了哪几点呢?首先我先说了一个打了个比,打了一个比较是吧,哎,奶站和用户订订牛奶的这么一个案例,在这里面呢,我们又说到了啊,说到了一个subject呢,将来会有三个核心的方法。三个核心方法,一个是注册的方法,所有的观察者模式都有这个啊,你放心好了,如果他没有这个名称,他那一定不是这种规范的观察者模式,好这个弄完了过后呢,我这有一张图。针对这个subject的一个示意图,我就放到这里了。好,接下来就是这么一个东西,好这个说完了以后呢,我们又干什么事呢?我们说一下观察者模式的一个接入啊,就是它的接入是怎么回事,接入呢,我这粘过来啊。
10:00
一样的道理,也是一个是observe接收的一个接入的说明,还有一个呢,就是观察者模式的一个说明,注意听,以后只要涉及到对象这件事,多对一的这种依赖大家就可以考虑啊,我们观察者有多对一的关系对吧?多对一的关系,那么这个示意图呢,我也给同学们拿过来啊,好,同学们。这就了。这是原理啊,然后这个说完了过后呢,我们就画出了我们的一个什么呀,示意图,就待会儿呢,我们要这么干。大伙有没有,这是我的一个设计方案。啊,设计方案我画了一个示意图。啊好,设计方案呢,我们也给他整理到这里来,很简单,设计方案就是刚才我在这画的这个图。拿过来吧。呃,注意看这个图的关系,将来是,呃,注册和移除是他主动发出。好,这个就就整完了。
11:00
好,因素关系,那下面呢,我们直接来看一下这个代码啊代码代码呢,也其实是特别简单的代码,看起来分析那么多,其实特简单,那第一步呢,我们先创建一个subject的一个里面先声明,呃,这个register observe remove。OB和一个notify or,那么OB这个observe server呢?只需要写一个接口把它提出来。好,现在呢,我们来写一下这个东西,现在我们用的是观察者模式,好,来走一个。新建一个包包。好,这个叫oper,直接写oper。ERV。观察者模式啊。啊,模式呢,它应该是这个PA partner啊partner应该更更准确一点,好,现在呢,我们先写出第一个treat啊走。那么这个取个名字叫。
12:03
好,里面呢,有三个核心的方法,这个我就不写了,哎,这个相信同学们刚才已经说过了啊,就是三个结构,好,我写到这里来。这个什么呢?这个是subject啊,Subject是一个什么呢?是一个接口啊,是一个treat,就是以前的接口啊,有些人可能叫直接叫接口也是可以的,里面有个啊不是,那么我在这个地方是干什么,就是注册。这个就是注册,大家看到就是注册啊,这个呢就是。啊,就是。二。好,这是明目,这个呢,就是通知对吧,就是通知。好,那么这个observer呢,Observer这样子,我们observer呢,我们这还没写,它也是一个接口。好,我们再新建一个opera OB serve ver新结构,那就是trade。
13:03
对,这里边儿呢,你也要给我去声明一个方法,就那个核心的update方法。那么啊,方法在哪里呢?同学们看我在这儿呢,也写了一段代码,对不对啊,也写了一段代码,这个是。Update的方法。Update的方法好,Update的方法呢?我们只是没有实现而已,这是一个抽象方法。这是个抽象方法,那么等待谁去呢?等待第三方,等待其他的这个观察者,观察者。去实现这个方法。观察者实现。好的啊,实现。属性。好,他等待谁预时间,那下面我们来就来写几个吧,咱们就来写几个,好,我们现在呢来写一个,呃,把那个原先这个当前的就是先就是气象局本身的那个天气预告版先写出来,我们再写一个新浪的啊,待会不写这个,我我换一个,好,那么我们新建一个current这个,这个代码和新建非常相同,只是有一个地方改了一下啊。
14:11
改了,有一个地方改了一下,其实这个就跟刚才是一样,只是他继承oper,其他几乎没有变化。啊,其他没有变化,也就是说原先我们写的这个东西可以直接拿来用,哪一个呢?就是我们在写这个地方的,它是可以拿来用的。它是可以拿,那我就写到这吧,来走一个。好,同学们,我先写一个叫currentn car。康。Condition,好,来写到这啊conditions,那么这边呢,我们要去继承。啊,继承谁呢?他继继承observe。啊,不是肯定的,那里面呢,肯定有方法。方法就是刚才我们所说的这个update方法,那update的方法呢,同学们看到啊。
15:01
阿,这个方法我们先写过来,那在哪里呢?同学们看这边已经有一份了,我想就不去写了啊,呃,干脆把这个方法拿过来用用就行了,我也不去写它了。好,干脆整个整个拿过来吧啊。只是这边呢,咱们写上这个over over right啊,重写它,因为格式我是保持一致的,这就写完了。啊,这就写完了,这个相当于是天气局的。就气象局的,气象局的。气象局的这个公告板。啊,听起来这个很哆嗦是吧,但是没办法,好气象局拉钩,我们再来这个气象局怎么用呢?好,气象局怎么用我们再写一段代码来用它一下,这段代码呢,就是我这写的这个下面这段代码就是whether data,要用起来这段代码呢,看起来就比刚才要多一点东西了,那么把这个写一下。它是一个subject,就是等待别人来进行注册。
16:04
的一个,呃,一个subject,它实现了subject,那么我们也来写一下。走新建一个类好,这个类呢,它去继承谁呢?它要继承subject好,这里面有核心的三个方法,你必须予以实现。予以实现,就是刚才我们所说的一个注册对不对,好一个。彝族。一个。什么呢,一个通知,好,这里面肯定是有一个集合的。肯定有个集合用于管理,用于管理所有的观察者。哎,你要去,你要去管他吗。好,这个地方同学们代码。我就不写了,要这样写的话得写好久啊,写好久我就。用用吧。用用好有几个地方我写的地方我留留留一下啊,像S带到这个地方,我我这样我可以自己就就用用一下好用一下就行了,这个这个代码我用一下。
17:09
好,这个集合呢,就在这儿。这个集合就是这个就是集合,那么现在呢,我这里用的是一个叫list buffer。这个是一个可变的,因此呢,我要引包。好,我要以下这个我们前面学的集合的这个可变list buffer,下面这些方法。保留不变,这个也不用变,里面这个注册我要写一下了。怎么来呢?如果有一个observe来了,他调用到我的注册,我就直接将它加入到哪里去。加入到我的集合之中进行管理。看清楚了,这样就可以做到动态了,非常简单一句话,Observe,哎,同学们,List里面怎么加一个东西啊,是不是用end就可以了呀?可以用A喷的吗?啊,Pen pen好有扔进去完事。
18:03
啊,就加进去了。加进去了,来一个就加一个嘛,那么如果要移除呢,咱们可以简单判断一下,比如说这个object observe点它里面有没有这个呢?先判断一下哎,有没有这个东西O有吧,好,如果有。啊,我们就当然前面这个也可以作为判断是吧?啊,如果说这个有呢,我们就把它移除了,移除也很简单。哎,移除是瑞木吗?瑞木好像不好使,哎瑞木,因为瑞木它是按照这个什么呀所引来的,咱们不能这么干,咱们用这个方法是学过吧,啊学个这样子学直接用个O。O。这可以吗?可以的是吧,例子的里面这样这样减掉一个对象可不可以,可以的,如果有我们就删掉,就跟我刚才写的代码一样,看看,如果有我就移除嘛。对吧,那注册我很简单,我就openend最后一个这个地方叫通知。
19:03
啊,这个就是这个就是移除什么意思呢?就是人家不干了,人家人家不愿意接受了,就说比如某个第三方,第三方不想。不想接入了,要退了,要退退会是吧,不想接入。你要不玩了,觉得没没用,每一个月花1万块钱不划算,要退了,那么这个时候就移除,那么这个就通知。通知什么意思,说一旦我的天气有变,就是说天气情况有变,比如每天定时都可以啊,天气情况变化了。变化了就怎么呢,我们就我们就通知所有的观察者,诶观察者能理解吧,那观察者你肯定要变利了,那就for循环嘛,那么我们先把这个observe取出来,1V从这取呢,从这个observe里面取。对不对啊,我这面去,那取出来过后我们干什么呢?我们就通知他嘛,诶你刚才人家是实现一个方法的喽。
20:08
是不是都实现这个update的方法了?好,很简单,那现在代码就变得easy了,怎么做呢?咱们就observe.update。你update的时候,你update的时候,这个时候这个这个信息从哪来,咱们不要着急,先等到这。行,等到这,诶同学们,你们原先这个调的时候,你在调的时候是不是这个。晒的就是这个地方,是天气变化的时候,气象局本身会掉一次是吧,这是天气变化了。天气变化。天气变化,那么天气变化的时候,它其实已经在这里把信息最新信息去掉,它又带到进那原先这个地方看。大家限定是不是我在这已经掉了这个这个不要这句话啊,就说一旦天气变化,是不是我去调了这个通知所有观司层。
21:04
一旦。一旦天气。天气变化。天气变化就就通知就通知所有所有观察者啊,所有观察者。好,非常简单,那你这肯定最新信息,其实我已经在这儿可以拿到了是吧,拿到过后这边大家清记就说他一定要晒站。把信息给了,给了过后我调现金,现金调我同时所有,那其实这个地方的信息已经拿到了,就是我们的当前的。这信息已经给你了,好,所以说简单这点啊,就直接写了啊M。这个温度湿度。对吧,是哎不是是有压力,好像是压力M压力。压力再来一个就是什么呢?诶就是它的思路写完了。
22:01
写完了,好,这个就能通知所有,那现在呢,我们来用一下,你先写完了,你能用一下吧,啊这问题能用一下吧,好,现在呢,我们来用一下,看看能不能。比原先要轻松很多了呢,来看一下啊,首先我们来做一个测试。Ne weather we,好,来一段代码啊,这个我写成object。好,还是一个主函数啊,前面有段代码能用,我就拿来用一下,来整个这个逻辑,诶这个地方是谁啊。Where the Dayton?哦对,我原先改的时候就故意写了两个,就把它改,还改改回去啊,还改回去是我以前那个设计的时候这样做的啊。好,这个呢,我们我们还把它改回去,诶把它改回去,好这个地方就是我们自己的这个y data,我拿来用一下。好,怎么用呢?现在用法就发生变化了。
23:00
现在用法就发生变化了。首先。我们来看看怎么用第一个。我们先创建一个气象局自己的天气公告板。创建完了过后,这个地方这个天气啊,就不需要再这样加了,不不需要了,我们这个地方的weather data就是自己的y data。我们看一下。我们用的是哪一个呢?用的是自己的Y,看这个构造器。我其实。没有直接放一个observe。就是他实验我不知道有哪些,所以说我根本就不需要放,那这个时候相当于说这方我没有传参输进去,那引下包。我引的是哪一个呢?引的是这个observer,用的是这个observer里面的这个好用完了过后我们要做什么事情呢?好注册。就是让他去注册。这个注册就可以了。注册,那注册的时候很简单嘛,我就让他说我要注册来了啊,我就register。
24:06
啊,这个是这样子注册啊。注册我们是调用。调用谁呢?With the data。点注册一下。Just,怎么调不出来呢?啊,我们看看是在哪里。啊,Whether data里面,哎whether data,哦,这写错了,这写错了啊ST哎这么说我这地方是ST啊。这个是他subject是他啊,我们刚才这个构建的构建错了,是他。啊,是他才对,对吧,是他才对,好,然后呢,我也带把这个ST也加上去。啊。我就在叠加上去,当然我们来完成一个注册任务,他来了我们就注册一下。点。点什么呢?注册register。
25:02
啊,被解释这个地方是我们给别人的啊,我们给别人,那这个时候怎么注册呢,我把自己放进去。啊,有一个人来了注册加进去,加进去以后,然后呢,我一旦有数据变化,我就调它就可以了,好,我们来先来运营一下,看看此时此刻能不能跑起来,好这样运行。我们看到这个效果已经出来了。好,现在呢,我们来做一个扩展,假如现在有第三方来了。是新浪的一个天气公告板,我们看。这个时候会有多简单,假如现在有一个第三方的这个这个公告板来了,我们写一个啊,比如说这是新浪。新浪的这个什么condition。啊,新浪的current当前的conditions好写完了,那写完过后呢,我只需要干什么呢?我只需要去继承,我是一个观察者啊,我是一个观察者吗?啊不是好在这里呢,这个观察者,这个观察者里面该写什么,你就写你的东西就行了,那么我们比对着原先这个来写就可以了,原先这段代码它有,其实说白了就是一个display,这个这个我也一样的,我就拿过来用一下。
26:19
好放到这里来粘贴,粘贴过呢,我改一下,比如显示的时候呢,我写的是新浪。新浪的天气公报版,新浪的。天翼公版,新浪天翼公版,我写完了,其他的东西不用变,那不用变,大家看啊,主要是观察我有没有改动别人的代码,你看我没有做任何别人的代码,我没有变化。我没有变化,然后呢,我回到这儿,回到这儿我我可以远程调用啊,现在因为目前在本地我也没办法远程调用,我没有去修改这里面的源代码,就是他的源代码。我无需做任何变化。啊,那我怎么用呢?那简单,我比如说创建了一个。
27:03
创建。啊,创建创建一个新浪的公告版,天气公版,天气公告版。那怎么做好快速的走一个就六一个新浪。然后点VR。放进去,那么这个公报版来了过后,我怎么办呢?好,我只要去完成一个注册就可以了,就是M点我要注册你,我要注册你,我注册谁呢?我把我自己放进去。就是这个人。他他只要能拿到这个地方的这个持有他的一个对象实力,这个很简单,因为阿卡我们都知道阿卡是可以持有一个远程的。的一个引用,我只需要如果用网络的话,其实就发一个消息过去就行了,发一个remove,或者是哎,这个是怎么是remove哦,我注册发一个注册消息不就完了吗?好当我你看我我只加了两句话,我加了两句话加了一个类,我是这样做啊,我为了增加一个,我加了两句话,加了一个类,但是我没有对任何代码进行修改。
28:14
原先是不行的,原先要修改代码,然后写对,我没做,现在我的事情就已经搞定了,来,走一个。你看我代码就跑起来了。大家看这里新浪的就拿到了,那有些同学老师这个分给不同的人有什么好处吗?新浪肯定在推荐这个天津公告时候,他可以加入自己的业务逻辑,你比如说新浪你要想做的更人性化一点,它在显示的时候,他他想这样显示,如果当前的温度,他比如说这个温度干什么呢?诶如果这个温度它大于了。大于了40度,哎,它就可能这样提示,他怎么提示呢?哎,他说当前温度是这样子的。啊,这么高,然后他加句话,赶紧啊,赶紧。啊,他说赶紧诶。
29:03
赶紧离开,离开地球啊,比如它这样子大于十度离的,那如果说要是if对吧,他说我的温度现在是大于这个16度,并且这个temperature小于,因为它每个。不一样嘛,比如它小于这个28度,诶,他说现在的温度很好,他就提示,诶现在温度特别特别好,那么他就说赶紧赶紧回到地球对吧?哎,赶紧回到地球,那这样子回回到地球。啊,回。回到地球。哎,就这意思,那么这样子我们就可以加不同的业务逻辑来展示,就说我我这个沙发这个只有一个目的,把信息推给你,至于你怎么显示,那是你的事,你看现在如果我这样做了过后呢,我也没有改动别人的,但是我显示效果又不一样,这是这是温度,看到没有,好,我走一个温度。看两个人的提示信息就不一样了。你看这边是,诶行了。
30:02
八九怎么没有了?啊,30度不都不在这个范围里面啊,整高一点,这个地方70度70度呢,你看人家心脏就就有温馨提示,让你赶紧离开地球对吧,气象局它就没有。当然你还可以调整一个比较合适的温度,比如说诶,现在咱们在20度啊,20度呢,这个温度特别好说,这个它有提示的是对吧,赶紧回到题,所以这样子大家可以感受到它的一种设计还是非常好的,那么如果我们放在一个网络上来看,它还有个什么好处呢?你的代码都不用重启。就你遥望原遥远的服务器,因为你不修改代码吗?你不修改代码,如果这个新浪它持有这一个VR data的一个I引用,其实我发一个消息,我只要发一个消息过去,那么我就让在消息接收那地方动态的给它完成一个register,那代码就自动的推进去,而且没有任改变,就是说我服务器那头,或者说我们这个核心的Y的那头没有做任何改变。
31:09
功能就增加了。同学,同学们就去仔细的体会他的一个。精妙之处就是它这个,它这种设计理念还是非常。非常好的一种方法,好同学们,那关于这个代码呢,我们就讲到这儿,我把代码给大家整到这边了啊,就是观察者模式的一个说明,下面呢,就是代码实现,诶代码实现我给他整了一些一些这个内容放到这了,代码实现具体来说呢。诶,就是刚才我们讲的这一部分内容,把它放过来。复制一下。啊,复制一下。好,然后呢,我把它打一个包包,诶打一个包包,就是我们刚才讲的什么呀,就是代码实现。代码代码实现OK。Okay。好,同学们,代码实验放到这里。
32:02
好,截取一段视频。
我来说两句