2011-04-07 72 views
6

是否有關於何時應使用代表進行間接關聯以及觀察者的指導?代表與觀察者模式

在C#中,您可以使用委託進行簡單回調。我猜想指向函數的指針和指向成員函數的指針也可以被認爲是委託(我是對嗎?)。

我意識到,使用觀察者,你需要創建一個接口,並實現它,所以它是更強類型和關係更正式。對於代表,只要功能簽名和可訪問性匹配,就可以「掛鉤」。

代表們是否讓觀察者模式無意義?你如何決定委託人與觀察員模式?

+2

順便說一句:在.NET 4中,這些接口已經存在:'IObservable '和'IObserver '。而且你可以使用Reactive Extensions輕鬆組成觀察者和觀察者。 – 2011-04-07 15:48:05

+0

請參閱http:// stackoverflow。com/questions/550785/c-events-or-an-observer-interface-pros-cons – jpierson 2011-05-19 03:52:59

回答

8

觀察者模式已經以events的形式爲您執行。

事件的優點是它們可以有多個訂閱者,而使用委託只能有一個。這會使公共接口的事件變得更好,並且您無法完全控制誰想要知道發生了什麼情況。事實上,事件只是自動管理的代表名單。你必須看到你的情況下更有意義。

編輯:As commenter Rabbi mentions,上述不完全正確,因爲任何委託可以成爲一個多播委託。事件修飾符的用途是創建一個只能在定義它的類中調用的委託。這對確保公用接口中的封裝非常有用。

+0

事件只是一種特殊類型的委託。是不是讓代表可以有多個訂閱者?我認爲一個事件是一個只有運營商'+ ='和' - ='的代表,並且委託也可以被分配('='),所以當你使用委託而不是事件時,你可以覆蓋所有的用戶。我對麼? – Rodi 2011-05-10 14:04:05

+0

事件的C#概念對某個代理或多或少是某個屬性對於某個字段的意義。您可以更改添加/刪除操作的功能,請參閱示例2 [此處](http://msdn.microsoft.com/zh-cn/library/8627sbea(v = vs.71).aspx)。如果不這樣做,它會爲您提供一個[MulticastDelegate](http://msdn.microsoft.com/en-us/library/system.multicastdelegate.aspx)。 – 2011-05-10 14:42:59

+0

是的。我想說的是,事件只使用運算符'+ ='和' - =',儘管你可以通過使用類似於屬性的'add'和'remove'構造來改變這些運算符的行爲。賦值('='運算符)不能在事件上完成。我可能是錯的,因爲我懶得去嘗試。 – Rodi 2011-05-23 10:05:48

1

代表可以用來實現觀察者模式 - 考慮事件。

要做到這一點,而不事件看看這裏:http://www.dofactory.com/Patterns/PatternObserver.aspx

它不會花費太多重構到這一點,如果你用最好的代表。

我認爲實現接口的唯一優點是所有實現中的成員名稱一致性。

3

觀察者模式的一個優點是,如果您有大量通常由感興趣方訂閱的事件,那麼將單個對象傳遞給訂閱事件的方法比訂閱事件更容易每個事件單獨。由於C#缺乏爲匿名類as can be done with Java指定接口和方法,因此實現觀察者模式變得更加麻煩,所以大多數人都選擇使用事件。

傳統的觀察者模式的另一個好處是,如果出於某種原因需要詢問用戶,它的處理效果會更好。我遇到了這樣的需求,即通過Web服務邊界的對象存在代理問題,而觀察者模式僅僅是對另一個對象的引用,因此只要序列化保持對象內的引用完整性,它就可以正常工作就像NetDataContractSerializer一樣。在這些情況下,根據被引用的用戶是否也在同一個對象圖中,可以區分在提供服務邊界之前應該刪除的用戶。