架构算法设计模式和编程理论程序员

如何让孩子爱上设计模式 ——15.观察者模式(Observer

2017-03-07  本文已影响207人  coder_pig

标签: 设计模式初涉


描述性文字

本节讲述的是:观察者模式(Observer Pattern),如果你用过RxJava,相信你对
这个模式应该不会陌生,当然,RxJava是扩展的观察者模式,这里不做了解,只
讲解最简单的观察者模式,首先是使用场景,举个最简单的例子,你放学到家,
很饿,这个时候你妈在厨房做饭,因为你和妈妈达成了写完作业才可以玩农药的
约定,所以你要先写作业,但是你又很饿,你想当饭做好了第一时间能吃到,你
可以:

上面的场景,使用观察者模式,比起反复的检索,显得更加优雅。

这个模式,有两个主要角色:被观察者观察者,这里的老妈就属于
被观察者,而你属于观察者,可能你还有个妹妹和弟弟,一起等饭吃,即:
一个被观察者可以对应多个观察者,你妈做好饭的时候,会把你们都通知一遍。

主要角色就这两个,当然,按照设计模式的套路,肯定是会抽象的,
所以有了另外的两个抽象被观察者抽象观察者,四个角色责任如下:

四个角色


一条简单的笔试题示例

先不画UML类图,我们来写个最简单的观察者模式例子,这个题目是上周去随手记
笔试的题目,大概题目是这样的:

花有两种状态,开和关,对于这两种状态,蜜蜂有两种行为,花开的时候采蜜,
花关的时候回巢这样,然后自己设计类结构,花与蜜蜂解耦,要用到一种设计模式
实现,输出如下结果,并画出UML类图。

花开
蜜蜂1采蜜
蜜蜂2采蜜
蜜蜂3采蜜

花闭
蜜蜂1回巢
蜜蜂2回巢
蜜蜂3回巢

题目内容大概是这个样子,看完地图第一个想到的设计模式就是观察者模式,
套路:把花假定为被观察者,蜜蜂为观察者,蜜蜂对花进行订阅,当花的
状态改变的时候通知蜜蜂做对应操作。
(因为当时刚从珠海过来,而且浪了一周,基本是裸面,知道这个东西,但是
写不出代码,2333,贼尴尬,后来通过接口回调的方式实现了...)

下面就用观察者模式实现上面的题目,首先定义一个抽象观察者——昆虫类

然后是具体观察类——蜜蜂类

接着是抽象被观察者 —— 植物类,注册,移除,通知观察者

再接着是具体被观察者 —— 花朵类,定义一个集合存储观察者,实现相关方法

最后是客户端调用

输出结果:

好的,用观察者模式实现就这么简单,代码都有了,画UML类图就手到擒来了~

UML类图


观察者模式的推与拉

推方式

被观察者对象向观察者推送主题的详细信息,不管观察者是否需要
推送的信息通常是被观察者对象的全部或部分数据

拉方式

被观察者对象再通知观察者时,只传递少量信息。如果观察者需要更
详细的信息,可以主动到被观察者中获取,相当于观察者从被观察者
中拉取数据。一般的套路是:把主题对象自身通过update()方法传递
给观察者,然后观察者在需要获取的时候,通过这个引用来获取。

拉方式代码示例

微信订阅了某个公众号,当有更新的时候会推送提醒,收到提醒后,
我们需要进入公众号然后点击对应信息查看详细内容。

抽象观察者用户具体观察者安卓开发者

抽象被观察者公众号具体被观察者CoderPig公众号

客户端调用

输出结果

好的,拉的模式就那么简单,就是通知观察者更新的时候,把对应引用
也传过去,然后观察者要什么查什么而已。


Java中对观察者模式的支持

在java.util包里面有一个类Observable,它实现了大部分我们需要的目标的功能;
还有一个接口Observer,它里面定义了update的方法,就是观察者的接口。
这个就更加简单了:
口诀:被观察者实现继承Observable,观察者实现Observer接口
然后有个很关键的地方:当通知变化的时候,需要调用setChange()方法!!!!

改写下上面的例子,代码如下:

输出结果

好的,同样很简单,就是不用自己另外去写抽象观察者或被观察者类,直接
继承就能玩了,另外有一点要注意的是:Java内置的观察者模式通知多个观察
者的顺序不是固定的,如果对通知顺序有所依赖的话,还是得自己实现观察者
模式!


概念相关拾遗

关于观察者模式的使用基本就上面这三点,接着说下定义,使用场景,优缺点

定义

定义对象见的一种一对多的依赖关系,当一个对象的状态发生改变时,
所有依赖于它的对象都得到通知并且自动更新。

使用场景

优缺点

优点

缺点


本节代码

https://github.com/coder-pig/DesignPatternsExample/tree/master/14.%20Observer%20Pattern

上一篇下一篇

猜你喜欢

热点阅读