设计模式 --- 观察者模式

观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。

优点:

​​1.解耦性强​​
​​观察者(订阅者)与主题(发布者)通过抽象接口通信,不直接依赖具体实现,​​修改主题或观察者的代码时,无需影响对方,提升代码可维护性。
2.​​动态订阅机制​​
​​观察者可随时注册或注销,运行时灵活调整事件响应,支持热插拔功能,增强系统扩展性。
3.​​一对多通信高效​​
一个主题状态变化可同时通知多个观察者,避免重复调用逻辑,提升事件处理效率。
​​4.支持事件驱动架构​​
通过事件总线(Event Bus)实现全局通信, ​​简化跨模块通信,适合复杂系统交互。

缺点:

1.​性能开销​​:
高频事件(如每帧更新)或大量观察者时,遍历通知列表耗时(物理引擎的CollisionEvent在百个对象碰撞时,触发千次通知)。
​​优化​​
1.使用事件合并(如积累多次位置更新后批量通知)。
2.异步处理(将事件推送到队列,分帧处理)。
2.​​内存泄漏风险​​:
​​观察者未正确注销时,Subject(主题者)持有其引用导致无法回收(Unity中,UI面板销毁前未取消订阅事件)。
​​优化​​
使用弱引用(WeakReference)或者使用扩展方法在MonoBehaviour绑定取消事件注册的方法,使其在OnDestroy时调用取消注册方法。

public static void UnregisterOnDestroy(this MonoBehaviour obj, Action unsubscribe) {obj.gameObject.AddComponent<OnDestroyDispatcher>().OnDestroyEvent += unsubscribe;
}class OnDestroyDispatcher : MonoBehaviour {public event Action OnDestroyEvent;void OnDestroy() => OnDestroyEvent?.Invoke();
}

注:弱引用的使用 (会加一篇Unity中弱引用的测试使用的文章)。
3.​​事件顺序不可控​​:
​​观察者处理事件的顺序依赖注册顺序,可能导致逻辑错误。
​​优化​​:
引入优先级字段,按优先级排序观察者。
4.​调试困难​​:
​​问题​​:事件流分散,难以追踪事件触发源头和传递链路。
​​优化​​:
添加事件日志:记录每个事件的发布者和订阅者。

说明例子:

1.UML图:

2.实现:

1.实现Subject(主题者)基类:

    public abstract class Subject{List<Observer> m_Observers = new List<Observer>();//加入观察者public void Attach(Observer theObserver){m_Observers.Add(theObserver);}//删除观察者public void Detach(Observer theObserver){m_Observers.Remove(theObserver);}//通知所有观察者public void Notify(){foreach (Observer theObserver in m_Observers){theObserver.Update();}}}

2.实现Observer(观察者)基类:

    public abstract class Observer{public abstract void Update();}

3.实现具体Subject:

    public class ConcreteSubject : Subject{string m_SubjectState;public void SetState(string state){this.m_SubjectState = state;this.Notify();}public string GetState(){return this.m_SubjectState;}}

4.实现具体Observer:

   //实现Observer1public class ConcreteObserver1 : Observer{ConcreteSubject m_Subject = null;public ConcreteObserver1(ConcreteSubject theSubject){this.m_Subject = theSubject;}public override void Update(){Debug.Log("ConcreteObserver1.Update");//获取Subject状态Debug.Log("ConcreteObserver1 : Subject 当前主题:" + m_Subject.GetState());}}//实现Observer2public class ConcreteObserver2 : Observer{ConcreteSubject m_Subject = null;public ConcreteObserver2(ConcreteSubject theSubject){this.m_Subject = theSubject;}public override void Update(){Debug.Log("ConcreteObserver2.Update");//获取Subject状态Debug.Log("ConcreteObserver2 : Subject 当前主题:" + m_Subject.GetState());}}

游戏中使用场景:

​​1.成就/统计系统​​:监听关键游戏事件(击杀、死亡、收集)--->玩家击杀Boss后解锁成就。
​​2.UI更新​​:将UI元素与游戏数据解耦--->血量变化时自动刷新血条UI。
​​3.跨系统通信​​:避免系统间直接引用--->背包系统物品使用后通知技能系统。
​​4.AI行为触发​​:基于事件触发的敌人反应---->玩家进入警戒范围触发敌人警报。
​​5.网络同步​​:将本地事件广播给其他客户端--->玩家位置同步事件。

总结:

观察者模式的核心价值​​在于解耦和动态通信,但其性能、内存和调试问题需谨慎处理。
在游戏开发中,观察者模式适用于以下场景:
1.需要松耦合的跨系统通信。
2.需要动态处理大量事件类型
3.需要支持模块化扩展(如MOD系统)。

参考书籍:

《Hands-On Game Development Patterns with Unity 2019》

《设计模式与游戏完美开发》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/79108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PasteForm框架开发之Entity多级嵌套的表单的实现

你相信么,使用PasteForm框架开发&#xff0c;管理端居然不要写代码&#xff01;&#xff01;&#xff01; 一起来看看PasteForm是否支持多级表模式(外表) 需求假设 假如有这么一个需求&#xff0c;就是订单表&#xff0c;包含了多级的信息&#xff0c;比如这个订单包含了哪些…

深入解析分类模型评估指标:ROC曲线、AUC值、F1分数与分类报告

标题&#xff1a;深入解析分类模型评估指标&#xff1a;ROC曲线、AUC值、F1分数与分类报告 摘要&#xff1a; 在机器学习中&#xff0c;评估分类模型的性能是至关重要的一步。本文详细介绍了四个核心评估指标&#xff1a;ROC曲线、AUC值、F1分数和分类报告。通过对比这些指标…

多模态医学AI框架Pathomic Fusion,整合了组织病理学与基因组的特征

小罗碎碎念 在医学AI领域&#xff0c;癌症的精准诊断与预后预测一直是关键研究方向。 这篇文章提出了Pathomic Fusion这一创新框架&#xff0c;致力于解决现有方法的局限。 传统上&#xff0c;癌症诊断依赖组织学与基因组数据&#xff0c;但组织学分析主观易变&#xff0c;基因…

《Python星球日记》第27天:Seaborn 可视化

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 专栏&#xff1a;《Python星球日记》&#xff0c;限时特价订阅中ing 目录 一、Seabor…

【scikit-learn基础】--『监督学习』之 决策树回归

决策树算法是一种既可以用于分类&#xff0c;也可以用于回归的算法。 决策树回归是通过对输入特征的不断划分来建立一棵决策树&#xff0c;每一步划分都基于当前数据集的最优划分特征。 它的目标是最小化总体误差或最大化预测精度&#xff0c;其构建通常采用自上而下的贪心搜索…

解决安卓开发“No Android devices detected.”问题

解决安卓开发“No Android devices detected.”问题 ​ 当我们插入移动设备的USB时&#xff0c;却发现这并未显示已连接到的设备 点击右侧的Assistant,根据提示打开移动设备开发者模式并启用USB调试模式,然后发现我们未连接到移动设备的原因是ABD服务的原因 问题确定了&…

idea如何使用git

在 IntelliJ IDEA 中使用 Git 的详细步骤如下&#xff0c;分为配置、基础操作和高级功能&#xff0c;适合新手快速上手&#xff1a; ​一、配置 Git​ ​安装 Git​ 下载并安装 Git&#xff0c;安装时勾选“Add to PATH”。验证安装&#xff1a;终端输入 git --version 显示版本…

软件架构设计:MVC、MVP、MVVM、RIA 四大风格优劣剖析

MVC、MVP、MVVM 和 RIA 都是软件架构中常见的设计风格&#xff0c;以下是对它们的详细介绍&#xff1a; 一、MVC 架构风格&#xff08;Model - View - Controller&#xff09; 1.简介&#xff1a;MVC 架构风格将软件应用程序分为三个核心部分&#xff0c;通过这种划分来分离不…

Centos/RedHat 7.x服务器挂载ISCSI存储示例(无多路径非LVM)

客户让帮忙挂载个ISCSI存储&#xff0c;大概结构如下图所示&#xff1a; ISCSI存储为一台安装了truenas的X86服务器&#xff0c;提供存储服务的IP地址为10.16.0.1 服务器的ETH1网卡配置与10.16.0.1同段网络。 为了给客户做个简单培训&#xff0c;整理了一下操作步骤。下面是配…

TV板卡维修技术【二】

【一】测量未知MOS引脚定义的好坏 TO-252封装的MOS管子&#xff0c;上面的大焊盘是D极&#xff0c;下面的3个不同品牌的NMOS或者PMOS验证了这个结论&#xff1a; 利用这个特性&#xff0c;可以在不知道MOS引脚定义的情况下测量出MOS的好坏&#xff0c;如下图&#xff1a; 插件…

基于 cefpython 实现嵌入 Chromium (CEF)

CEF Python是一个开源项目&#xff0c;旨在为Chromium Embedded Framework提供Python绑定&#xff0c;许多流行的GUI工具包都提供了嵌入CEF浏览器&#xff0c;例如QT。 安装 pip install cefpython366.1支持的Python版本&#xff1a; 实现打开网页 from cefpython3 import…

MySQL-存储引擎和索引

1.MySQL的基础架构是什么&#xff1f; MySQL由连接器、分析器、优化器、执行器和存储引擎这五部分构成。 一条SQL的执行流程&#xff1a; 通过连接器连接数据库&#xff0c;检查用户名和密码&#xff0c;以及权限校验&#xff0c;是否有增删改查的权限。在MySQL8.0之前&#…

安卓性能调优之-掉帧测试

掉帧指的是某一帧没有在规定时间内完成渲染&#xff0c;导致 UI 画面不流畅&#xff0c;产生视觉上的卡顿、跳帧现象。 Android目标帧率&#xff1a; 一般情况下&#xff0c;Android设备的屏幕刷新率是60Hz&#xff0c;即每秒需要渲染60帧&#xff08;Frame Per Second, FPS&a…

【运维自动化-标准运维】职能化功能如何使用?

职能化功能主要用于一些固化的标准流程可以通过权限开放的方式给到那些负责固定职能的非运维人员&#xff0c;比如外包操作员来执行操作&#xff0c;如此可以释放一些运维的人力&#xff0c;让其可以专注流程的建设和优化。实操演示 新建职能化流程&#xff08;运维角色操作&a…

游戏引擎学习第224天

回顾游戏运行并指出一个明显的图像问题。 回顾一下之前那个算法 我们今天要做一点预加载的处理。上周刚完成了游戏序章部分的所有剪辑内容。在运行这一部分时&#xff0c;如果观察得足够仔细&#xff0c;就会注意到一个问题。虽然因为视频流压缩质量较低&#xff0c;很难清楚…

【小沐学GIS】基于C++绘制三维数字地球Earth(QT5、OpenGL、GIS、卫星)第五期

&#x1f37a;三维数字地球系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第二期3【小沐学GIS】…

OpenAI 最新发布的 GPT-4.1 系列在 API 中正式上线

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【力扣】day1

文章目录 27.移除元素26. 删除有序数组的重复项 27.移除元素 26. 删除有序数组的重复项 我们仔细看一下这两道题的最后的返回值,为什么第一题返回slow 而第二题返回slow1 最后的返回值该如何返回绝对不是凭感觉,我们自己分析一下第一个slow,从0位置开始, 遇到val值就开始和fas…

完全无网络环境的 openEuler 系统离线安装 ClamAV 的详细步骤

准备工作&#xff08;在外网机器操作&#xff09; 1. 下载 ClamAV RPM 包及依赖 mkdir -p ~/clamav-offline/packages cd ~/clamav-offline/packages# 使用 yumdownloader 下载所有依赖包&#xff08;需提前安装 yum-utils&#xff09; sudo dnf install yum-utils -y sudo y…

3.2.2.2 Spring Boot配置视图控制器

在Spring Boot中配置视图控制器可以简化页面跳转跳逻辑。通过实现WebMvcConfigurer接口的addViewControllers方法&#xff0c;可以直接将URL映射到特定的视图&#xff0c;而无需编写控制器类。例如&#xff0c;将根路径"/"映射到welcome.html视图&#xff0c;当访问应…