观察者模式

参考资料:

https://www.imooc.com/learn/415

https://blog.csdn.net/itachi85/article/details/50773358

观察者模式模式实践代码

目录

1、什么是观察者模式

2、观察者模式的2种实现方式

3、观察者模式的2种实现方式的比较

4、观察者模式的的角色

5、观察者模式的优缺点

6、观察者模式的应用场景

7、观察者模式的衍生

8、观察者模式的结构

9、观察者模式的通用代码

10、观察者模式的本质

11、从六大方面观察者模式

12、利用JAVA提供的观察者实现


1、什么是观察者模式

定义:

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

其他定义参考:

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

注:一对一属于一对多;

一个目标可以有任意多个观察者对象,一但目标的状态发生了改变,所有注册的观察者都会得到通知,各个观察者会对通知做出相应的响应,执行相应的业务逻辑处理;

2、观察者模式的2种实现方式

(1)推模型

目标对象主动向观察者推送目标的详细信息,推送的信息通常是目标对象的全部或部分数据;

注:不管观察者是否需要 ,推送的信息通常是目标对象的全部或部分数据;

(2)拉模型

目标对象在通知观察者的时候,只传递少量信息。

如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于是观察者从目标对象中拉数据。

一般这种模型的实现中,会把目标对象自身通过update方法传递给观察者。

3、观察者模式的2种实现方式的比较

  • 推模型是假定目标对象知道观察者需要的数据;
  • 拉模型是目标对象不知道观察者具体需要什么数据,因此把自身传给观察者,由观察者来取值;
  • 推模型会使观察者对象难以复用
    解释:因为观察者定义update()方法,是按需来定制的,可能无法兼顾没有考虑到的情况,这就意味着出现新情况的时候,就可能需要提供新的Update方法,或者干脆重新实现观察者,而拉模型就不会造成这样的情况;
  • 拉模型下,update方法的参数是目标对象本身,基本上可以适应各种情况的需要;

4、观察者模式的的角色

  • Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  • ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  • Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  • ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

5、观察者模式的优缺点

优点:

第一、观察者模式实现了观察者和目标之间的抽象耦合

解释:原本目标对象在状态发生改变的时候,需要直接调用所有观察者对象,但是抽象出观察者接口以后,目标和观察者就只是在抽象层面上耦合,也就是说目标只是知道观察者的接口,并不知道具体的观察者的类,从而实现了目标类和具体的观察者之间的

第二、观察者模式实现了动态联动

解释:所谓联动,就是做一个操作,会引起其他相关的操作,由于观察者模式对注册实行管理,那就可以在运行期间通过动态的控制,注册的观察者来控制 某个动作的联动范围,从而实现动态联动。

第三、观察者模式支持广播通信

解释:由于目标发送通知给观察者,是面向所有注册的观察者,所以每次目标通知的信息就要对所有注册的观察者进行保护,当然也可以在目标上添加新的功能来限制广播的范围

缺点:

可能会引起无谓的操作;

解释:

由于观察者每次都是广播通信,不管观察者是不是需要,每个观察者都会被调用update方法,若观察者不需要执行相应的处理,那么这些操作是不是就浪费了,其实浪费是新的问题,最怕引起误会,就麻烦了。

其实模式的应用,就像孙子兵法的36计,具体用在什么样的战场上,就要看用计的人能不能熟练应用。

在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。

6、观察者模式的应用场景

  • 关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系。
  • 事件多级触发场景。
  • 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

建议在以下情况中选用观察者模式:

第一 当一个抽象模型有2个方面,其中一个方面的操作依赖于另一个方面的状态变化;

解释:将这2者封装成观察者和目标对象,当目标对象变化的时候,依赖于它的观察者对象也会发生相应的变化,这样就可以把抽象模型的这两个方面分离开,使得他们可以独立的改变、复用

第二 如果在更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟应该有多少对象需要被连带改变

注: 这种情况,被更改的对象很明显是目标对象,而需要连带修改的其他对象就可以当作是多个观察者对象

第三 当一个对象必须通知其他的对象,但你又希望这个对象和其他被它通知的对象是松散耦合的;

注:这个对象不想知道具体被通知的对象,这种情况可以选用观察者模式,这个对象就相当于是目标对象,而被他通知的对象就是观察者对象;

7、观察者模式的衍生

TODO

8、观察者模式的结构

9、观察者模式的通用代码

步骤:

1)、是目标对象的定义

2)、是具体的目标对象的定义

3)、再来看看观察者的接口定义

4)、看看观察者的具体实现

10、观察者模式的本质

当修改目标对象的状态的时候,就会触发相应的通知,然后会循环调用所有注册观察者对象相应的方法,其实就相当于联动调用这些观察者的方法

理解观察者模式的本质很重要,对我们识别和使用观察者模式具有重要的意义,尤其是在练习使用的时候万变不离其宗

11、从六大方面观察者模式

(1)目标与观察者之间的关系

按照模式的定义,目标与观察者之间是联系的,是一对多的关系;

一个观察者可以对多个目标;

如果观察者为多个目标定义了通知,更新的方法都是update方法的话,这样会带来麻烦需要接收多个目标的通知,若是一个update方法,需要在方法内部区分。一般情况下观察者应该为不同的观察者目标立不同的观察方法;

(2)单向依赖

在观察者模式中,观察者和目标是单向依赖的,只有观察者依赖目标,而不是目标依赖观察者,他们之间的联系,主动权掌握在目标者的手中,只有目标知道什么时候需要通知观察者,在整个过程中观察者是被动的,被动的等待目标的通知,等待目标传值给他;

(3)命名建议

1)目标接口的定义,建议在名称后面跟Subject;

2)观察者接口的定义,建议在名称后面跟Observer;

3)观察者接口的更新方法,建议名称为update

(4)触发通知的时机

在实现观察者模式的时候,一定要注意触发通知的时机,一般情况下是在完成状态维护之后触发,因为通知会传递数据,不能先通知后改变数据,这很容易出问题,会导致观察者目标和对象状态不一致;

(5)观察者模式的调用顺序

TODO

(6)通知的顺序

从理论上来说,当目标对象的状态变化后,通知所有的观察者的时候,需求是不确定的,因此观察者实现的功能绝对不能依赖于通知的顺序,也就是说,多个观察者之间的顺序是平行的,相互不应该有先后依赖的关系

12、利用JAVA提供的观察者实现

JAVA实现与自己实现的对比(四点):

(1)不需要再定义观察者和目标的接口了,JDK帮忙定义了;

(2)具体的目标实现里面不需要再维护观察者的注册信息了,这个在java中的Observable类里面已经帮忙实现好了;

(3)触发通知的方式有一点变化,要先调用setChanged方法,这个是JAVA为了帮助实现更精确的触发控制而提供的功能;

(4)具体观察者的实现里面,update方法其实能同时支持推模型和拉模型,这个是JAVA在定义的时候,就已经考虑进去了;


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

推荐阅读更多精彩内容