Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;观察者模式:添加另一个维度_C++_Design Patterns - Fatal编程技术网

C++ c++;观察者模式:添加另一个维度

C++ c++;观察者模式:添加另一个维度,c++,design-patterns,C++,Design Patterns,我试图在一个“智能建筑”系统设计中实现这个模式(使用STL库)。放置在房间、楼层等的各种“传感器”,由“控制器”处理的调度信号(也放置在不同的房间、楼层等)。我面临的问题是,控制器对事件的订阅不仅基于事件,还基于位置 例如,控制器A可以订阅4楼1号房间的火灾信号和5楼的运动信号。基于楼层的订阅意味着控制器A将获得一个关于他订阅的楼层中每个房间的运动事件(假设适当的传感器放置在那里)。对于这一点,还有一个建筑范围的订阅 系统的拓扑结构是在启动时从配置文件中读取的,所以我不想映射整个建筑,只想映射包

我试图在一个“智能建筑”系统设计中实现这个模式(使用STL库)。放置在房间、楼层等的各种“传感器”,由“控制器”处理的调度信号(也放置在不同的房间、楼层等)。我面临的问题是,控制器对事件的订阅不仅基于事件,还基于位置

例如,控制器A可以订阅4楼1号房间的火灾信号和5楼的运动信号。基于楼层的订阅意味着控制器A将获得一个关于他订阅的楼层中每个房间的运动事件(假设适当的传感器放置在那里)。对于这一点,还有一个建筑范围的订阅

系统的拓扑结构是在启动时从配置文件中读取的,所以我不想映射整个建筑,只想映射包含传感器和控制器的相关位置

我的想法是:

选项1:monitoradera包含区域名称(Building1,Floor 2,Room 3)和向量的索引为枚举事件类型的向量的类向量的每个成员包含订阅此事件的控制器列表。如果是楼层中的房间或建筑中的楼层,则该类还将包含一个指向父Monitoredera的指针

传感器类将向中心集线器发送事件以及传感器名称。中心将通过其传感器名称运行到位置图,获取匹配的监视器数据并向向量中的所有控制器发出警报

缺点

  • 位置与控制器的耦合
  • 事件是枚举的,并且在monitoradea类中硬编码,因此很难添加将来的事件。
选项2: 保留控制器类中的所有订阅

缺点

  • 效率很低。每个事件都会使控制中心遍历所有控制器,并找出订阅此特定事件的控制器
选项3: 基于事件的功能。事件类(即FireEvent)将包含它可能发生的所有位置(根据传感器的设置),并且对于每个位置,都将包含订阅它的控制器列表

缺点

  • 地图
  • 强大的数据重复
  • 无法向基于楼层的订阅通知各个房间中的事件
正如你所看到的,我对上面提到的任何解决方案都不满意。我相信我已经到了深思熟虑的阶段,我很乐意得到关于我如何处理这件事的反馈或其他建议。谢谢。

在游戏开发中,有一种被称为“消息总线”的设计模式(可以说)被大量使用。它有时被用来代替基于事件的操作

“消息总线是一个或多个发送方和/或接收方之间的连接。将其视为总线拓扑中计算机之间的连接:每个节点都可以通过将消息传递到总线来发送消息,所有连接的节点都将接收该消息。是否处理节点以及是否发送回复完全取决于每个接收方本身。”

将模块连接到消息总线给了我们一些优势:

每个模块都是隔离的,它不需要知道任何其他模块。 每个模块都可以对发送到总线的任何消息做出反应;这意味着您可以免费获得额外的灵活性,而不会增加依赖性。 遵循YAGNI工作流程要容易得多:例如,你要添加武器。首先你要实现物理,然后在渲染器中添加视觉效果,然后播放声音。所有这些功能都可以在任何时候独立实现,而不会相互中断。 您不必考虑如何将某些模块相互连接。有时需要花费大量时间,包括绘制图表/依赖关系图。”

资料来源:


谢谢您提供的信息。问题:消息总线与简单事件循环有何不同?我不确定是否正确理解了您的问题,但这是在类型化语言上实现方法调度的不同方式。例如,您可以在总线上发送消息,并使用带有ID和一些数据的结构,如果另一个类对该特定ID感兴趣(有许多实现),则可以处理它。对象之间没有直接的函数调用,就像在常规方法调用消息调度中一样。