2011-09-23 198 views
4

时,何时和谁分离观察者,我使用公司中不同组提供的第三方库(用C++编写)遇到此问题。当观察者的观察者的寿命长于可观察到的

在Observer的析构函数中,它将它自己从它所订阅的所有观察对象中分离出来,这部分对我来说很有意义。但是在Observable的析构函数中,它会检查observable是否有任何观察者仍然在订阅者列表中。如果是这样,则会引发错误。

我打算把它故意抛出析构函数的错误放在一边。有人可以试着向我解释为什么观察者不应该期望观察者活得更远,或者这只是一个糟糕的设计。如果这是一个糟糕的设计,那么当我们处于观察者超出观察者范围的情况下时,是否有很好的方法来处理它?

+0

我只是想知道为什么观察者的寿命会比观察者短(假设观察者确实是一个观察者,意味着它只要存在观察者就需要观察观察值)。 – Nawaz

+0

我没有很好的答案。我有一个观察是这个库使用了智能指针(boost :: shared_ptr)和原始指针的混合。这个特殊的问题在关机时出现。这可能是因为命令做了一些其他的对象仍然拥有观察者的shared_ptr。 – dln

回答

5

如果Observer有一个指向Observable的指针(或引用),并且Observable被销毁,那么这个指针将是无效的。作者只是试图避免悬而未决的引用。

我想有三种常见的解决方案。

一个是做这个代码做的事情,也许调用abort()而不是在析构函数中抛出一个异常。

另一种方法是让Observable的析构函数从任何观察者中注销自己。

最后是使用“智能指针”(例如,引用计数的shared_ptr)来保证Observable超过任何观察者。

+0

感谢尼莫。正如你所说,观察者类确实持有指向它所订阅的所有观测值的指针。我想在这样的设计下,我们隐含地认为观察者并没有超过可观察的。 – dln

+0

我认为'deregister'方法是最明智的。然后观察者可以做出适当的反应。 –

0

这取决于上下文。我期望一个完全通用的 实现观察者模式,以支持删除一个观察到的对象,至少可以选择,但有很多用途,其中 没有意义,并且可能是编程错误。一般而言,在可观察到的完全破坏之前,它应该通知其观测者 它将破坏的事实;他们应该然后解除。这意味着 ,在调用可观察注册表对象的析构函数为 时,应该没有注册观察者。

0

我通常以相反的方式实现模式 - Observable添加自身并将自己从Observer的列表中删除。我的观察者在整个应用程序的整个生命周期中都存在,通常观察者会活几秒钟。

+1

如果你以这种方式实现,那么观察者将如何知道它是潜在的观察者? – Nawaz

+0

@DeadMG:您的可观察性是否在某些框架之上实现? (请参阅维基百科关于观察者模式和发布 - 订阅模式之间差异的文章。) – rwong

-1

这只是糟糕的设计,没有什么能保证观察者能够胜过所有的观察者。

如果您有权访问observable的析构函数,请重写它,以便将它的所有观察者分离。