I encountered this problem using a third party library provided by a different group in the company (written in C++).
In the destructor of Observer, it detaches itself from all observables it subscribes to, this part makes sense to me. But in the destructor开发者_运维知识库 of Observable, it checks if the observable has any observer that's still in it's subscriber list. If so, throws an error.
I am going to put the fact that it intentionally throws an error in the destructor aside. Can someone try to explain to me the why the observable should expect no observers to outlive itself or is this just a bad design. If this is a bad design, when we are in circumstances when the observer outlives the observable, are there good ways to handle it?
If the Observer has a pointer (or reference) to the Observable, and the Observable is destroyed, that pointer will be invalid. The author is just trying to avoid dangling references.
There are three usual solutions, I think.
One is to do exactly what this code does, perhaps calling abort() rather than throwing an exception in the destructor.
Another is to have the Observable's destructor de-register itself from any Observers.
The last is to use "smart pointers" (e.g., a reference-counted shared_ptr
) to guarantee that the Observable outlives any Observer.
It depends on the context. I would expect a totally generic implementation of the observer pattern to support deleting an observed object, at least optionally, but there are a lot of uses where this doesn't make sense, and is probably a programming error. In general, before the observable fully destructs, it should notify its observers of the fact that it will destruct; they should then unenrol. Which means that by the time the destructor of the observable registry object is called, there should be no registered observers.
I usually implemented the pattern the other way around- the Observable adds itself and takes itself away from the Observer's list. My Observer lives throughout the whole lifetime of the application, and the Observables live a few seconds, typically.
It's just bad design, nothing guarantees that the observable will outlive all of its observers.
If you have access to the observable's destructor, rewrite it so it will detach all of its observers remaining.
精彩评论