2011-09-23 249 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的析構函數,請重寫它,以便將它的所有觀察者分離。