【发布时间】:2012-10-10 16:48:14
【问题描述】:
我不知道是否有我需要的特殊关键字。我正在写一个基本的observer pattern,我担心一些问题。我的实现是经典的。我正在使用一个 std::set 观察者,每当我需要触发一个事件时,我都会遍历这个集合并调用每个观察者的 notify 方法。我的问题如下。在以下情况下,当可观察对象向观察者发送事件时会发生什么:
- 一个观察者想要在事件期间将自己(或任何其他观察者)从观察者集中移除?
- 一个观察者想要清除观察者集(移除所有观察者)?
- 一个观察者破坏了可观察对象?
我知道所有这些情况最终都会发生。我对第三个有想法,但这是题外话。对于第一种和第二种情况,问题在于删除或清除 std::set 将使我用来枚举可观察对象的迭代器无效。即使没有,observable 也不应该通知任何在事件处理期间将被删除的观察者。
我还没有找到一个 set 的实现,它提供了一个能够在删除任何项目时保持有效的迭代器。不过,有可能实现它,但代价是一些间接并在容器中存储对活动迭代器的任何引用,以便在必要时对其进行更新。
另一种解决方案是复制观察者集合,迭代副本并检查当前迭代的观察者是否仍在真实集合中。 (这会忘记在活动期间添加的任何新观察者,但这种情况我不在乎)
您对这个问题有什么建议/解决方案吗?
【问题讨论】:
-
您可以让观察者将自己标记为“todelete”,并让迭代代码在遇到如此标记的观察者时进行实际删除,而不是让观察者删除自己。
-
@StevenBurnap 这带来了一个语义问题:删除是立即生效还是在观察结束时生效?例如,如果 Observer4 删除了 Observer6,Observer6 是否仍会收到当前事件的通知?
-
啊...我没有仔细阅读并假设观察者只会删除自己。
-
@Robᵩ:好点,但通常的观察者模式不会以任何特定顺序通知观察者(事实上他使用的是
set而不是像vector这样的插入顺序容器表明这也是这里的意图),这意味着处理删除的唯一可靠方法是在通知所有观察者之后。 -
我的问题是当观察者删除 observable 时。如果一个观察者删除了另一个观察者,我假设被删除的观察者有责任在他的破坏期间将自己从集合中移除。这又回到了第一个问题:当一个观察者从活跃的观察者集中移除另一个观察者时该怎么办?
标签: c++ iterator observer-pattern