實際上,觀察者模式的實現如何避免由於重入導致的不良行爲?觀察者模式:避免不良的重入行爲?
爲了闡明「不良行爲」,考慮模式中的Subject有單線程方法MethodA()和MethodB(),事件OnMethodA()和OnMethodB()以及一個或多個Observers的情況同步實現:
- Subject.MethodA()被調用,
- 主題做什麼它爲methodA(),然後調用OnMethodA()爲所有的觀察員,
- Observer1得到OnMethodA( )事件,並調用Subject.MethodB(),
- 該主題做什麼它的方法b(),那麼對於所有的觀察員呼籲OnMethodB(),
在這一點上,我們稱之爲OnMethodB()所有觀察員,儘管我們仍然在通知中的中間爲OnMethodA()。這意味着列表中的Observer1之後的任何觀察者都將在「OnMethodA()」之前看到「OnMethodB()」 - 這是不好的行爲。
- Observer2(由誰不知道什麼Observer1一個開發者編寫)得到OnMethodB()事件,並調用Subject.MethodA(),
- ...永遠。 Subject.MethodA() - > Observer.OnMethodA() - > Subject.MethodB() - > Observer.OnMethodB() - > Subject.MethodA() - >等...
現在你要溢出堆棧。那是不好的行爲。
如果你已經設計了異步,基於隊列的通知,從一開始,或通知期間拋出的通話主題的例外,就可以避免這一點,這是很容易理解。有什麼困擾我的是,我幾乎從來沒有把這種做法看作是實施該模式的最佳(或者真的,唯一的)做法。你必須已經意識到谷歌「觀察者模式可重入」的問題,並且搜索結果似乎只是遇到問題的人,而不是關於模式的書中的警告。
所以我錯過了什麼? 在實踐中,Observer模式的實現如何避免由於重入導致的不良行爲?