游戏设计模式读书笔记:观察者模式与事件队列

观察者模式

定义

  • 定义:在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。
  • 看图


模式的理解

  • 观察者模式由来已久,其目的就是为了解耦。观察对象保存观察者的链接,使得观察者与被观察者解耦。这一点与C#中的事件刚好相反。
  • 传统的观察者模式也有其弊端。比如书中提到的使用链表作为观察者集合时,如果删除某个观察者需要遍历。并且每个观察者只有一个next指针的情况,这就使得它只能观察一个对象。当然作者也给出来解决的办法,就是使用链表节点池来解决一个观察者注册多个被观察者的问题。不过在C#的事件系统中这个是不需要的。
  • 当出现被观察者或者观察者销毁时需要额外的注意。一个被观察者销毁产生的问题比较小,因为最多就是不发送消息了。而如果一个观察者销毁但是被观察者还不知道,那么被观察者会发送一个消息给空指针,这样问题就大。 在C#中这个问题也是一样的,当要dispose的时候,需要使用-=操作来去掉观察引用。

观察则模式和事件的区别

  • 长久以来我都认为C#中的事件就是观察者模式,当然实际上有所差别。因为按照经典的设计模式来说观察者是需要类的支持的,当你需要让某个对象可被观察,并为此创建几个观察者时你需要执行诸如继承这样的典型的面向对象编程,需要做一大摊子的事情。但是,很多情况下我们只是希望一个类中的某个对象被观察,也就是一个对象中可能发生多个事件。这也是C#中事件系统所作的事情,在C#中我们观察的是一个对象,而不是一个事情。(参考原文的旁白说明。)

在unity中的使用

  • 这个其实没啥说的,就按照标准的C#程序中使用事件的方式即可,只不过我比较习惯用Action或者Func来替代delegate+event。

事件队列

  • 对于事件队列,不要只认为是事件,它也包含消息或者请求等等。按照我的理解来说就是一个具体要做的事情。
  • 为何要把事件队列和观察者模式写到一起,因为在我看了它们的作用是一样的,就是为了解耦消息的发送者(被观察者)和接受者(观察者)。事件队列在复杂度上要高于观察者模式,这个是因为事件队列在时间上做了进一步的解耦。
  • 怎么理解时间上的解耦?事件队列在接收到一个事件后,何时执行是不确定的。考虑到事件会带上发生时的数据,那么在执行时是不需要依赖时间的。
  • 时间的解耦有个弊端,就是如果你需要实时反馈,那么这个做不到。
  • 还有一个需要注意的是不要形成消息和处理者的循环。

消息汇总与合并

  • 书中作者提到了一个声音播放系统,当队列中存在多个相同音频的请求时需要进行合并。当然这个是因为同一音频短时间内容播放会出现音爆。不过这个也提醒了我们,如果在实际的业务中有这样需要合并的时候,在每个update(也就是要开始执行某个事件时)中要进行合并。

如何实现队列

  • 作者提到了循环缓冲区的问题,通过使用一个数组来实现消息队列,这样可以有效的减少内存的使用。不过我认为弊端就不好定一个数组的大小,如果过小可能来不及做循环,而如果太大一样存在内存的浪费。
  • 从C#角度看,这个队列可以Queue来实现,可以说是完美契合的。

设计决策

  1. 入队的是什么:
    • 事件:如果是事件需要考虑多监听器的情况下让监听器做过滤。其实这个就是一个观察者模式。在这里就有点像异步观察者模式。
    • 消息:一般消息都是一对一的,这个其实也是异步的意思。
  2. 谁能从队列里读取:
    • 事件的话轮到了执行就好,有没有监听者无所谓。如果是一个固定类型的消息,那么可能就是一个具体的业务的方法来获取队列中的消息了。
  3. 谁能写入队列:
    • 如果只有一个写入者,那么这个东西在时间上会执行的很快,和同步的观察者模式差不多。
    • 如果是多个写入者,需要将发送方本身的引用加入到事件的数据当中。就像我们在C#中开发基于UI的程序一样,如果你有经验会知道每个事件处理函数中第一个参数总是某个具体的控件。
  4. 队列中对象的生命周期
    • 在我看来应该就是事件出队列时就是其周期的结束,当然因为GC的问题这个对象也许并不会立刻被销毁。
    • 书中提到了可以将对象的所有权进行转移,到具体的执行方去。也可以让队列一直拥有它。这个方面我还没有觉得有这个必要保留对象,也许是没有遇到一个典型的例子吧。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容