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

标签: 设计模式初涉


描述性文字

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

  • 每隔一段时间跑去厨房找你妈,问她饭做好没(轮询
  • 跟你妈说一声,"老妈,饭做好了马上叫我"(订阅或注册),你妈答应了你
    的请求,等她做完饭后立马通知你,这样你就不可以一心一意的做作业了,
    等你妈通知你,然后放下手上的作业,去吃饭。

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

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

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

四个角色

  • Subject抽象被观察者,把所有观察者对象的引用保存到集合中,然后
    提供添加移除和通知观察者对象更新的方法
  • ConcreteSubject被观察者,集合存放观察者,重写增删和通知观察者
    的方法,当发生变化时通知观察者更新。
  • Observer抽象观察者,定义一个更新接口,给被观察者更新的时候调
  • ConcreteObserver具体观察者,继承抽象观察者,实现具体的更新方法

一条简单的笔试题示例

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

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

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

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

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

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

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

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

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

最后是客户端调用

输出结果:

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

UML类图


观察者模式的推与拉

推方式

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

拉方式

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

拉方式代码示例

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

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

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

客户端调用

输出结果

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


Java中对观察者模式的支持

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

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

输出结果

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


概念相关拾遗

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

定义

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

使用场景

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立
    的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象将
    发生改变,也不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,
    可以使用观察者模式创建一种链式触发机制。

优缺点

优点

  • 实现了观察者和目标之间的抽象耦合
  • 实现了动态联动(一个操作会引起其它相关的操作)
  • 支持广播通信

缺点

  • 互为观察者与被观察者间有循环依赖的话,要注意相互通知引起的死循环!
  • 可能会引起武威操作,误更新。

本节代码

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容