【设计模式】observer(观察者)-- 对象行为型模式5.7
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的更多相关文章
- 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)
设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...
- 设计模式18:Observer 观察者模式(行为型模式)
Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...
- 设计模式(3)-对象创建型模式-Abstract Factory模式
1.对象创建型模式 1.3 Abstract Factory模式 1.3.1 需求 在下面情况能够使用Abstract Factory模式: • 一个系统要独立于它的产品的创建. ...
- 设计模式(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) - ...
- Java经典设计模式之十一种行为型模式
转载: Java经典设计模式之十一种行为型模式 Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式 ...
- Java设计模式——Observer(观察者)模式
在多个对象之间建立一对多的关系,以便当一个对象状态改变的时候.其它全部依赖于这个对象的对象都能得到通知,并被自己主动更新. 适用情况: 当一个抽象模型有两个方面,当中一个方面依赖于还有一方面. 将这二 ...
- Java经典设计模式之十一种行为型模式(附实例和详解)
Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之 ...
- Java设计模式之十一种行为型模式(附实例和详解)
Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J设计模式之五大创建型 ...
- java架构之路-(设计模式)五种创建型模式之单例模式
设计模式自身一直不是很了解,但其实我们时刻都在使用这些设计模式的,java有23种设计模式和6大原则. 设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可 ...
- Java设计模式16:常用设计模式之观察者模式(行为型模式)
1. Java之观察者模式(Observer Pattern) (1)概述: 生活中我们在使用新闻app,当我们对某一栏比较感兴趣,我们往往会订阅这栏新闻,比如我对军事栏感兴趣,我就会订阅军事栏的新闻 ...
随机推荐
- [ActionScript 3.0] as3启动QQ
import flash.html.HTMLLoader; import flash.net.URLLoader; import flash.net.URLRequest; import flash. ...
- 【vue】——CDN或全局引入CSS、JS。
在入口文件index.html中添加 <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- java_I/O字节流
I/O流(Stream) INPUT:输入流,从文件里读OUPUT:输出流,写内容到文件 IO流分为:字符流和字节流 字符流:处理纯文本文件. 字节流:处理可以所有文件. 测试字节输出流OuPut(写 ...
- c/c++ int,float,short 大小端转换函数
unsigned int(uint32_t)大小端转换函数 unsigned int BLEndianUint32(unsigned int value) { return ((value & ...
- C. Edgy Trees Codeforces Round #548 (Div. 2) 【连通块】
一.题面 here 二.分析 这题刚开始没读懂题意,后来明白了,原来就是一个数连通块里点数的问题.首先在建图的时候,只考虑红色路径上的点.为什么呢,因为为了不走红色的快,那么我们可以反着想只走红色的路 ...
- asp.net 网站在Apache下的配置,就这么简单
asp.net 网站在Apache下的配置,就这么简单 # # Virtual Hosts # # If you want to maintain multiple domains/hostnames ...
- (转)mysql、innodb和加锁分析
mysql.innodb和加锁分析 原文:https://liuzhengyang.github.io/2016/09/25/mysqlinnodb/ 介绍 本文主要介绍MySQL和InnoDB存储引 ...
- Wrapper配置详解及高级应用(转)
转自:http://286.iteye.com/blog/1921414 将一个简单的程度如HelloWorld 的应用包装秤Wrapper 服务并不复杂,甚至可以认为非常简单.但是实际项目应用过程中 ...
- WCF系列教程之WCF服务协定
本文参考自:http://www.cnblogs.com/wangweimutou/p/4422883.html,纯属读书笔记,加深记忆 一.服务协定简介: 1.WCF所有的服务协定层里面的服务接口, ...
- java io流 数据流 DataInputStream、DataOutputStream、ByteArrayInputStream、ByteArrayOutputStream
例子程序: package io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import ...