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

时间:2016-03-19 12:32:35

标签: c++ design-patterns

我正在尝试在“智能建筑”系统设计(使用STL库)上实现此模式。放置在房间,地板等中的各种“传感器”发送由“控制器”处理的信号(也放置在不同的房间,楼层等中)。我面临的问题是控制器对事件的订阅不仅仅基于事件,而且基于位置。

例如,控制器A可以订阅来自#4楼中的房间#1和楼层#5中的运动信号的发射信号。基于楼层的订阅意味着控制器A将获得关于他订阅的楼层中的每个房间的运动事件(假设适当的传感器放置在那里)。这个问题还有整个建筑物的订阅。

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

我设法想到的是:

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

传感器类会将事件与传感器名称一起发送到中心集线器。集线器将通过其传感器名称到位置映射运行它,获取匹配的MonitoredArea并将警告向量中的所有控制器。

缺点

  • 将位置耦合到控制器
  • 枚举事件并在MonitoredArea类中进行硬编码,很难添加将来的事件。 enter image description here

选项2 : 保留Controller类中的所有订阅。

缺点

  • 非常低效。每个事件都会使控制中心遍历所有控制器,并找出订阅此特定事件的内容。

选项3: 基于事件的功能。事件类(即FireEvent)将包含它可能发生的所有位置(根据传感器的设置)以及每个位置,包含订阅它的控制器列表。

enter image description here

缺点

  • 地图地图
  • 强大的数据重复
  • 无法提醒有关各个会议室活动的楼层订阅。

正如您所看到的,我对任何提到的解决方案都不满意。我确信我已经达到过度思考的阶段,并且很乐意就我如何处理此问题提供反馈或其他建议。感谢。

1 个答案:

答案 0 :(得分:0)

在称为“消息总线”的游戏开发中有很多使用的设计模式(有点说话)。它有时用于替换基于事件的操作。

“消息总线是一个或多个发送器和/或接收器之间的连接。可以把它想象成总线拓扑中的计算机之间的连接:每个节点都可以通过将消息传递到总线和所有连接的节点来发送消息将收到该消息。如果节点被处理并且回复被发送完全取决于每个接收者本身。

将模块连接到消息总线会给我们带来一些好处:

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

来源: http://gameprogrammingpatterns.com/event-queue.html

http://www.optank.org/2013/04/02/game-development-design-3-message-bus/