2011-04-07 71 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一样。在这些情况下,根据被引用的用户是否也在同一个对象图中,可以区分在提供服务边界之前应该删除的用户。