00:02
我们使用观察者模式来解决天气预报的需求,首先呢,还是老规矩,老规矩,我们先画出这个类图来看一下。OK,那现在我们做一个改进,改进的话呢,这样的同学们,我们仍然在observe这个包包里面,我们新建一个纸包,叫改进方案。Improve。Pro pro,好,改进方案,那改进方案里面有些相同的地方,待会我再粘贴拷贝好不好,我现在先画一个图。OK,跟上我的思路,其其实挺简单,一目而了然。首先根据刚才的分析,我们应该画什么呀?是不是首先我们要把这个气象站,气象站的这个接口做出来,所以我先画个接口,这个呢,我们取个名叫subject。同学们,这个接口里面是不是至少要定义三个核心的方法,哪三个核心的方法来看一下第一个方法。是不是这里面呢,会有一个register。他。
01:02
是吧,什么类型呢?同学们,显然它。他这里面应该是定的observe。是不是在他那边应该是这样子的。诶,这个地方我们看看有问题啊,那这么加一个这样子就行了。它是这样一种格式。大家知道这是什么意思吗?就是说我可以注册,我注册什么呢?我可以把观察者注册到我这一个subject里面去,呃,有了注册是不是还有别的几个方法,还有什么方法,有remove方法。这个没问题吧,就是说比如说有一个观察者,他不想不想关注我们了,或者不想再再再关注我们的天气预报了,我们可以把它remove掉,那remove掉呢,同样道理,O。你把这个observe给我,我就把它干掉。A。好的。然后还有一个什么方法呢?Notify。是不是还有一个notify啊,就是通知我们所有的观察者有什么情况变化,Not。
02:04
Five no five是吧,Observers加个S好,这是那么这个写完了过后。这个写完了以后,我们是不是应该有个子类来实现它,那这个类就是哪个,就是我们传说中的YW,对的。是吧,我们讲可这个这个这个就是我们的weather data,那这个weather data呢,他一定会去干什么,实现这个subject。这个没问题吧,当然这里面就会把它三个方法做成做好,其实这里面还应该有个什么呀,肯定还有一个集合,对不对,那你想一想,你将来在这里面肯定要做一个管理,所以说我们我们这里面肯定会有一个集合,这是跑不了的。那这个集合呢,我们就用哪个来做呢,我们干脆简单一点啊,就用比如说我这里管了很多的observer。那么我们就用a list来存放吧。
03:00
Or list?好,我就演写到这里。好的。那这个weather data就是我们的核心类了。同学们可以分析出来,它是一个核心的,它这里面呢,呃,我们这有个注释。这个whether whether是核心类。它这里面包含的第一个是天气的信息。他首先有天气信息,第二个他要管理什么呢?他要管理所有的管理这个观察者。Observer。那这个所有的管理肯定就会有这个什么注册呀,通知啊等等等等。说这个应该是我们最为核心的一个类。好,除此之外,是不是我们还有观察者,观察者我们要做一个接口。Observer。这是一个接口,那么同学们知道observer里面呢,一定会有一个特别重要的方法,就是update方法,为什么?因为你你的update方法我不好去更新你呀,Update。
04:04
好,同学们可以看到这两者之间是什么呀,Subject会用到它,所以说我们认为它是一个依赖的关系。是不是那么observer它会放到这个这个里面,所以说我认为它是一个聚合的关系,它会聚合到我们这里面来,这个大家看能否理解。就是我这里面we data里面呢,有很多op observe,那具体的一个op observe,那就看你的,比如说有新浪。新浪这个网站。对吧,也可以是我们的网易,也可能是百度百度。他也可能是一个观察者。那我们前面写的是哪一个呢?我为了省事啊,我还用我们那个condition,就是current cu2current OK。这是天学,那么我们让他去干什么呢?实现这个OB接口。
05:04
看清楚了,说说从这从这里我们可以看出来,说白了就是这边是观察者,观察者会被我们y data干什么呢?管理。一旦有变化,那如果你要增加一个观察者呢?也很简单,怎么样,我在这加一个就行,而不再去修改我们Y的data,也就是说将来你要扩展。扩展子类,而这个weather data不需要做任何变化。不需要做任何变化,增加减少都可以,那我们客户端怎么用呢?来同学们看。那作为一个客户端来说呢,它首先会通过这个subject这个接口依赖到我们的we data,所以说我这画的是依赖subject,依赖subject接口,其实就是依赖subject接口的下面的具体的实现实现内,同样他也会去依赖observer,说依赖observer就是通过这个接口去依赖下面的指令。这样呢,也比较清晰,好,同学们图就画完了。
06:02
就这么简单。是不是很清晰啊,那这样子我们有了这个图,是不是应该用代码来走一遍,来同学们,现在呢,我们就来开始写代码,我们先写哪一个呢?来根据我的思路,首先我们先写出subject这个接口。需要的来吧,谢subject即可。四个接口,那这个接口里面呢,有这么一些方法,刚才老师已经说过了,是不是public void register。Observer。好的,那现在呢,Aer这个这个类还没有哈,马上就会创建的。Observer好,有这个还有什么呀啊。Mo,比如说我不要了,删掉它,还有一个notify。就通知。No t five什么observers?然后这个时候就不需要再传了,因为我要所有的通通知嘛。
07:02
好,这是个接口。OK,那这个接口呢,是他需要让谁呢,让。让这个weather weather data。来实现。是不是来实现。什么?呃,下面的一些方法,那observer我们先写出来,他也是个接口来写一个,不着急啊,同学们写一个接口叫observer。是观察者的接口。那既然是观察者接口。我们是不是应该把它最核心的方法叫update方法写出来,Update,那大家想想你update的时候应该传什么参数进去呢?肯定就是它的温度气压和它的湿度是不是,所以说我这传接受一下temperature这个怎么写temperature temperature是这样写吧,T。Temperature temperature。T。TE啊e temperature。
08:02
那么还有什么呢?气压flow,气压呢,我们用prayer。PSU。啊,Prayer还有一个什么呢?就是它的湿度。Hu me。You meet。Ity好像这样写的,Humidity humidityid humidity,这个是我们的思路。好,现在这个方法呢,也它也是个接口,它是一个观察者接口。观察者的接口。那有什么呢?有观察者。来实现。对不对,好,那既然这个有了过后,我们下面就没得说了,直接写上它的子类。那么我们先写哪个词类呢?来,同学们,我们先写current,根据刚才的思路啊,写current。Condition。是不是我们写这个conditions吧。
09:00
Conditions,那这个类呢,我想就不用一个一步的写了,因为前面呢,我们写过一点能拿来用的,我们拿来用。是不是这个还是有些是可以用的,拿过来吧。拿过来他该有的这些信息属性肯定还是要有的,那现在呢,我们来在这个基础上进行一个。适当的扩展update的方法,不用动。不用动,这个跟以前一样好,Display这个方法。不用动,不用动。呃,那现在呢,我们应该干什么呢?哦,这个这个这个方法其实完全都不用动。是吧,他因为他就是一个观察者嘛,所以说你调用我,我就我就显示,所以说他这种是完全一样的,就说跟我们原先写的。一样不需要改就行了啊t temperature t,那我这个单词刚才写的有点问题啊。把单词改一下。这样写的是吧,Temperature temperature单词别写错了。
10:01
好呃,那现在我们就完成了哪哪个呢,这个写了下面这个也写完了,Subject也写完,现在是不是就留下了一个wide data,那那么把这个y data呢,前面有的我先复制一份,哪些地方改我们再改就行了。拿过来了啊,同学们。那这个是核心,它包含最新的天气情况,还有这个抗,那现现在就不是含有一个了,而是含有一个什么呢?诶含有什么呀,就是含有这个观察者。集合。使用什么来管理呢?使用R历史的管理。同样当数据有更新的时候呢,他就会去遍历这个list。对不对,这样通知接入方最新消息。就会当时有就会主动调a list这个这个对什么呢?通知对通知所有的。通知所有的接入方。
11:02
让他们看到最新消息,同时他还要去实现那几个方法,所以说他呢会去implements。啊,刚才这个地方是少写了一个东西。这样去实现啊。他去实现,不然的话,你到时间放不进去这玩意儿。他要实现observer。刚才这少写了一句话。Update方法刚好也有了,所以说这个也是完全吻合的,那这边我data呢,它就是我们这个subject。下面的一个时限之类。好,同学们可以看到,当这个写完了过后,那就意味着我们这里面呢,有些方法需要实现,哪些方法呢,就是这三个方法需要我们实现。同时。这个地方就不再是。一个这样的东西了,而应该改成什么呢?同学们想一想。现在是观察者。哎,观察者集合了。是不是既是关照的集合,那么写写上了private什么呢?List里面放的就是。
12:08
AERVR,各位怎么接不进来哈,待会再说。那这个呢,我们写。这边我们引入相关的包。引入相关的包好这个就搞定了。那这个时候我们再进行这个,呃,这个weather。这个构造器的时候应该怎么写呢?这个时候就不要再指定传入一个了,没有用,你不能一个个的传,所以这个地方呢,我们要对它进行一个初始化就行了,应该改成什么呢?Observers等于六一个R。是不是对这个集合进行一个处理,那这里面放的什么呢?Observer。好,这样大家思路就很清晰了。好,现在这个有了过后这个地方肯定也也要改啊,我们待会再说怎么改。晒的方法呢,可以暂时不改,肯定要改,那大家想一想,怎么register一个东西呢?
13:07
怎么呢?那就是在我们的observers。Observers。诶,我们这儿实有个observe。是不是这个集合呀,爱的进去是不是就可以了,点艾艾的一个什么O就行了,是不是加进去,如果我们要移除一个是不是。Alber。干什么点remove是不是这个O啊,这就是移除,这个就是注册。注册一个观察者。是吧,那下面这个是干什么呀?这个是移除一个。移除一个观察者。那当然了,还有通知,那大想你通知是不是要把所有观察的通知啊,那就便利。便利所有的观察者并通知。
14:01
就完事了。那你想想你怎么去便利呢?怎么去便利呢?非常简单啊,这样子我们这加一个判断啊,安全一点就是首先我判断observe。这个里面有没有这个对象,其实一你在填的时候一般都会有的是吧,如果有我再去删除,这样呢,加一个验证notify怎么做,同学们。想想那是不是就是便利,那就负循环了来anti ti等于零,I小于。我们observers.size。一共有这么多观察者爱加加对吧,那我就一个一个编利,他说OB observe。取出一个点盖子。谁get I拿出来这个,这个不是移除就取出来啊,也就是说我们这个观察者并没有从observers里面干什么,移除掉,只是取出来看,然后调查的update的方法,因为你每一个观察者里面是不是都有update?好,这个时候我们把最新消息,把最新的给他就可以了,因为你在你在调这个notify的时候呢,肯定是要通过set这个来的,所以说这个地方我们就直接get就行了,Get我们的temperature。
15:13
啊,其实你也可以直接把这个属性写进去也是可以的是吧,你是因为这个地方肯定已经是最新的了嘛,所以这方也可以这样写。就是我们的Z4.temperature。是这样子吧,这个就是四点什么呀,我们的压力player,下面这个是Z4点,我们的什么呀,这一个湿度humanity。完事。这就是更新到所有,那现在大家想你在这个地方一旦有数据变化。一旦有数据变化。那么数据变化的时候,你先更新到自己,然后第二带change,那带change这个地方,原先你是通知一个,现在是不是要通知所有。那要通知所有。但诶这样是不是已经通知所有,那这个方法怎么调呢?OK那就明白了,你看啊,一旦掉天掉到陷阱,在这个带的change级里面,我们调用什么呀。
16:09
带在氢气里面。我们调用这个楼梯法。Notify observers就可以了。大家看是不是这个思路,看啊,当你有新的数据进去过后,我先更新,更新完了我调data change data change里面呢,我不再调这一个方法了,而是调notify observers notify呢,会去便利我们当前的这个观察者的集合,然后每一个都去更新一把。而这个update里面呢,大家看回到我们这个update,这个update就是我们current里面的update update里面人家display又去更新我们这个。公告版的,或者更新我们第三方的显示界面,代码就写完了。代码写好,现在这个代码写完过后,我们保存一下,看看能不能使使用一下。好,现在全部写完哈,写完现在我们就差一个东西了,哪个呢?
17:00
就差我们的这个兰,我们来使用一下,来调一个兰来用用,看看是否能够成功。诶,这个怎么建这个了。我们新建一个类客户端。Your c。OK主方法怎么勾上?那在这个时候我们应该怎么去调用呢?也非常简单,我们来首首先我们先干什么?创建一个weather data。1K2。Datata好,六一个啊,六一个Y塔,那就遛我们自己的。这个wide data就有了。那么y data有了以后,是不是我们就来创建观察者?创建关关。观察者,那观察者我们就写一个吧,比如说现在建立一个current conditions,拿到了一个观察者。没问题吧,好,我们把这个观察者呢,注册注册到哪里呀,注册到我们这个weather data里面去。
18:02
是不是很轻松的一件事情?呃,怎么怎么注册呢?那就是weather data里面它有个register,我们把这个OB观察者放进去。是不是注册进去了,注册进去以后,我们现在就可以来测试一下了,测试看看能否拿到,我现在比如说有最新消息。好,我们来走,一句话,测试我写啊,叫做干什么呢?通知,通知各个注册注册的观察者。观察者。我们看看看看信息。好,那这个时候我们怎么去做呢?非常简单,就y data,我只要动这就行了,点side好,然后呢,最新温度十度。气压100,湿度30.3。就写完了,诶这地方有问题是吗?Set。啊,它是都是float类型的,那我这没办法,这全部都要加个F。
19:02
好,这样就可以了。是吧,这样就可以来我们来玩一把,运行一下,看看是否都成功了。中药也可以看出来。通知各个助手观察者信息更新了,那有些同学老师这个也跟以前一样啊,但是大家有没有发现这种东西的扩展性就会很好。那假如现在我有一个百度公司有个百度,百度呢,他想来得到我们最新的消息,你看我怎么加,我只需要在这加一个,其他地方不用变。就说我们只需要加一个百度。那么百度可以展示他自己的页面吗?在这加一个新的观察者过后呢,同学们,这个地方不做虚,这这个这个wide data作为它的使用方来说,它不需要做任何变化,我们直接就可以在在哪里呢?在client里面用了还是很方便,来加一个试试看,我们加一个百度。OK啊,百度。百度这个网站吧,Site。OK啊呃,那么这个百度赛呢,他也成为一个观察者了,所以说他要去实现observer。
20:07
他要实现哦,这个是肯定的,他一段时间的话呢,显然他这边也有一些方法要去做update方法,那么我这次就抽过来啊,我在这边稍微的给他改发一下就行了好吗。嗯,大体的思路一样,我就是让它显示的内容不一样就可以了,好偷个懒改一下,呃,这些基本上一样。那这边我们改一下,就是说百度最新。百度百度。嗯,应该怎么写百度网站。这个。预报天气啊,天气这个叫做气温。气温。好吧,那么这边呢,是百度网站给我们提供的气压。气压。起样,OK,这个是百度网站给我们显示的什么呢?显示的这个思路。
21:01
OK。那也就是说,呃,当然你如果还有别的显示方式不一样,那你自己做嘛,可能你这显示的是一个表格,或者是显示的是一个比较好看的一个页面,或者是一个动态的显示效果,或者是呃,那个瀑布流的方式,这个就由你来决定好吧,但是基本上这个思路还是一样的嘛。就反正你要实现这个update,至于你这里面写的是呃,Display还是别的方法,至于怎么显示,那就是你的事了。好,就是我们这样一个行为,好,我这还可以写一句话,就是百度网站。这个百度网站。OK,百度网站。好的,那现在这个百度网站一加进去,你们看到啊,一个很有意思现象y data,我们不需要改变,我们直接在client里面就可以用了,怎么用呢,非常的简单,打开client。比如说现在呢,我们又有一个新的观察者百度来了。百度WEBSITE100度site。
22:02
好,我们只需要把百度site给我们干什么注册进去就行了。注册到哪里呢?诶register做为一个观察者,注册到我们的weather,呃,Data里面去就可以了,那这个时候你会发现,诶你就加了两句话,你会看到呢,诶怎么样,百度这边也能显示出来,来看一下。运行。我们可以看到,诶看到没有,百度网站说百度的新闻是这样子的,这样子这样子对不对,还是很方便的。所以说这个设计模式呢,在这就凸显出它效果了,假如我们不需要一个了,说了说那个,比如说根据你的一一个实际情况,你就删掉了。啊,比如说呃,打个比方。我们这个百度他又不玩了,或者是current condition他又不想玩了,我们可以把它移除掉,怎么移除呢?大家看我remove。呃,这个写错了。Remove。
23:00
呢,一个观察者,比如说这个current,他不想观察,他取消对我们的关注。取消对应关注,我们再通知,你会看到这个时候又会看到一个新的消息,我们打一个空格,你会发现什么呢?就是当前的这个信息只有百度了啊,或者说只有百度这个观察者了,来看一下。你看很灵活。是不是这是第一次的,第二次各个注册观察者只有百度了上面。就是呃,这个current condition这个观察者就没有了。非常方便。好,同学们,通过这个案例,我相信同学们应该对这个有所有所了解,对吧?多少有了解,我们再来看一下观察者模式的好处,观察者模式设计好了过后呢,会以集合的方式管理我们的用户,或者叫接入方,包括注册以储和通知,这样我们增加观察者的时候,可以理解成增加一个新的公告板,就不需要去修改我们核心的we data。就遵守了OCP的原则,这就是他的好处,那么这样子,我把这个类图呢,也给同学们放过来。
24:03
这个类图还是比较有意思,对不对,一目了然。通过这个观察者模式。我们。更好的管理了各个类。这就是他的好处。好,同学们,关于观察者模式来解决天气预报的这么一个案例就给大家讲解到这里,大家要认真的去体会。
我来说两句