1.意图

对象之间一对多的依赖关系,当目标对象发生改变时,所有依赖于它的对象都要得到通知并自动更新

2.别名

依赖,发布-订阅

3.动机

1)需要确保相互协作的对象的一致性(数据要保持一致),但一致性会使各个对象紧密耦合,减低它们的可重用性。

2)Observer模式描述了如何建立这种关系:一个目标(Subject)可以有任意个依赖于它的观察者(Observer),当目标发生改变的时候,所有观察者都得到通知(Notify);观察者响应通知(Update),会去查询目标状态(GetState)使其状态与目标状态同步一致。

3)观察者去订阅(Subscribe),目标去发布(Publish)

4.适用性

1)一个抽象模型有两方面,一方面依赖于另一方面,两者独立封装在不同对象里以方便各自独立的改变和复用

2)一个对象的改变需要通知另一个对象,而被通知的对象数量不确定

3)被通知的对象之间互相不知道对方是谁,没有紧密耦合

5.结构 & 6.参与者

7.协作

8.效果

1)目标与观察者之间的抽象耦合:目标不知道具体观察者是属于哪个类的,只知道他们符合抽象Subject的接口,具体目标本身也可以是各式各样的,只要符合Object抽象接口即可,所以耦合是抽象和最小的,目标和观察者可以属于整个系统中的任意一个层次。

2)支持广播通信:目标可以无脑广播给所有它的观察者,不用知道观察者是谁,是否响应处理通知可以放在观察者层去判断

3)意外的更新:A观察者不知道B观察者的存在,A的操作导致目标改变,会通知到B,若B其实不依赖目标(定义了错误的依赖关系)可能会导致大量无效的通知或者通知导致B观察者数据错误

9.实现

1)创建目标与观察者之间的映射:

  方法1:在目标里面存放观察者列表,简单,但目标多观察者少的时候存储代价会高一些

  方法2:用一个公共的对象来存储subjects 和 observers之间的映射

2)观察多个目标:

  Update里面传参数Subject,来告知观察者是哪个目标更新了

3)谁触发更新:

  方式1:目标对象的属性变更时由目标触发更新通知,好处观察者和其他对象不用关心何时触发更新不会出现遗漏,缺点是一个操作可能会导致多次更新,也会发多次通知

  方式2:由客户来触发更新通知,好处可以随时控制触发更新时机,避免中间更新,缺点会遗漏触发

4)对已删除目标的悬挂引用:

  通知目标的所有观察者把目标从身上的引用移除

5)在发出通知前确保目标的状态自身是一致的:

  方式1:Subject上的Notify在SetState之后调用,因为Observer里面的Update可能会从Subject上GetState

  方式2:用Template Method模式,即父类Subject中的模板方法把重定义操作Operation()放在Notify()之前,子类只要重定义Operation方法即可,就能确保操作完了才Notify

6)通知模型 推/拉

  push推模型:把详细信息都通知给所有观察者,不管他们是否需要;推模型假定知道观察者需要什么,但假定不一定正确可能使得观察者难以复用(收到了大量无用信息,自己想要的又没有推送)

  pull拉模型:只发送最小通知(如告诉观察者有更新了),观察根据自己需要从目标取他想要的数据;拉模型假定目标不知道观察者,但效率会低,因为在目标发送信息太少的情况下观察者无法知道目标到底改变了什么

7)显式的指定关心内容

  void Subject::Attach(Observer *, Aspect& interest);  观察者注册时指定关心的目标方面变更,目标只通知关心改变方面的观察者,并在Update里把Subject和Aspect都带上

  这个操作在Observer端做筛选其实也行。

8)封装复杂的更新语义

  更新管理器ChangeManager的职责,是个Mediator,Singleton

  a) 它将一个目标映射到它的观察者并提供一个接口来维护这个映射。这就不需要由目标来维护对其观察者的引用, 反之亦然。

  b) 它定义一个特定的更新策略。(比如N个目标都改变了才触发通知,或者目标在400ms发生改变只触发一次)

  c) 根据一个目标的请求, 它更新所有依赖于这个目标的观察者。

9)结合目标类和观察者类:

  两者可以放到一个类里

10.日常开发项目应用

1)跨服逻辑,gameserver是观察者,centerserver是目标;gameserver连上后会Attach到centerserver,断开就Detach, centerserver上的globalserver列表发生更新的时候需要Notify所有的gameserver,用于更新PK服列表信息

2)战斗逻辑,player是观察者,player和monster是目标entity;entity进入player可视范围Attach,离开Detach,entity移动后坐标发生变更,需要通知他周围的观察者player坐标变更,这里使用了ChangeManager(map)来管理这个依赖关系的映射,并且制定了更新策略:发生变更不立马通知,400ms tick的时候如果有变更则通知观察者

【设计模式】observer(观察者)-- 对象行为型模式5.7的更多相关文章

  1. 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)

    设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...

  2. 设计模式18:Observer 观察者模式(行为型模式)

    Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...

  3. 设计模式(3)-对象创建型模式-Abstract Factory模式

    1.对象创建型模式 1.3           Abstract Factory模式 1.3.1 需求 在下面情况能够使用Abstract Factory模式: •  一个系统要独立于它的产品的创建. ...

  4. 设计模式(4)-对象创建型模式-Prototype模式

    1.对象创建型模式 1.4          Protoype模式 1.4.1需求 通过拷贝原形对象创建新的对象. 1.4.2结构 •P r o t o t y p e(Gr a p h i c) - ...

  5. Java经典设计模式之十一种行为型模式

    转载: Java经典设计模式之十一种行为型模式 Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式 ...

  6. Java设计模式——Observer(观察者)模式

    在多个对象之间建立一对多的关系,以便当一个对象状态改变的时候.其它全部依赖于这个对象的对象都能得到通知,并被自己主动更新. 适用情况: 当一个抽象模型有两个方面,当中一个方面依赖于还有一方面. 将这二 ...

  7. Java经典设计模式之十一种行为型模式(附实例和详解)

    Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之 ...

  8. Java设计模式之十一种行为型模式(附实例和详解)

    Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J设计模式之五大创建型 ...

  9. java架构之路-(设计模式)五种创建型模式之单例模式

    设计模式自身一直不是很了解,但其实我们时刻都在使用这些设计模式的,java有23种设计模式和6大原则. 设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可 ...

  10. Java设计模式16:常用设计模式之观察者模式(行为型模式)

    1. Java之观察者模式(Observer Pattern) (1)概述: 生活中我们在使用新闻app,当我们对某一栏比较感兴趣,我们往往会订阅这栏新闻,比如我对军事栏感兴趣,我就会订阅军事栏的新闻 ...

随机推荐

  1. Nginx的反向代理和负载均衡

    1 Nginx的反向代理 1.1 什么是反向代理 正向代理 反向代理: 反向代理服务器是引用在服务端.决定哪台服务器提供服务. 1.2 反向代理的模拟 1.2.1 反向代理 应该有一个nginx服务器 ...

  2. net 反编译神器

    文章地址:https://www.cnblogs.com/sheng-jie/p/10168411.html dnSpy官网下载  分享链接 .net core源码导航 https://www.cnb ...

  3. Collections.singletonList方法的使用

    方法注释 /** * Returns an immutable list containing only the specified object. * The returned list is se ...

  4. MySQL的逻辑查询语句的执行顺序

    一.select语句关键字的定义顺序 二.select语句关键字的执行顺序 三.准备表和数据 四.准备SQL逻辑查询测试语句 五.执行顺序分析 一.select语句关键字的定义顺序 SELECT DI ...

  5. Jexus进程守护工具jws.guard

    一个运行中的进程,难免会因为各种各样的原因无缘无故的宕掉(比如网站瞬间的负载过高.内存不足等),而Jexus宕掉的后果往往只有一个:对外提供服务的网站无法访问了.因此,我们需要最大限度的保障我们的网站 ...

  6. windows下Composer因php_openssl扩展缺失而安装失败

    Composer(https://getcomposer.org/)是PHP下的一个依赖管理工具.你可以在你的项目中声明你所需要用到的类库,然后Composer会在项目中为你安装它们.如果你了解Nod ...

  7. MySQL3534

    1.mysqld install 2.mysqld --initialize-insecure自动生成无密码的root用户 3.mysql -uroot即可登录

  8. Java面试题-Java容器

    一.Java容器分类 Java容器划分为两个概念Collection.Map Collection: 一个独立元素的序列,这些元素都服从一条或多条规则.List必须按照插入的顺序保存元素,不关心是否重 ...

  9. Java 实现两个整数变量的交换

    class OperatorTest { public static void main(String[] args) { int a = 10; int b = 20; System.out.pri ...

  10. JavaScript自动化构建工具grunt、gulp、webpack介绍

    前端开发自动化工作流工具,JavaScript自动化构建工具grunt.gulp.webpack介绍 前端自动化,这样的一个名词听起来非常的有吸引力,向往力.当今时代,前端工程师需要维护的代码变得及为 ...