【发布时间】:2011-03-07 11:07:27
【问题描述】:
观察者设计模式似乎是通过其事件委托模型内置在 C# 中的。有什么理由我可能必须以经典方式实现它吗?
问候
123开发者
【问题讨论】:
标签: c# design-patterns
观察者设计模式似乎是通过其事件委托模型内置在 C# 中的。有什么理由我可能必须以经典方式实现它吗?
问候
123开发者
【问题讨论】:
标签: c# design-patterns
通常,语言中内置的事件模型足以满足观察者模式。真的没有理由以不同的方式实现它,因为您只是在重新创建事件。
话虽如此,人们很少改变“标准”事件模式。例如,我见过人们想要异步引发事件的情况。我通常不推荐这样做(我个人认为这在订阅者方面处理得更好),但它仍然可以通过标准 C# 事件来处理,但引发事件略有变化(使用 GetInvocationList 并异步调用委托) .
【讨论】:
你是对的。观察者模式是在 C# 事件系统中使用委托实现的。
您想要更接近经典观察者的第一个原因是聚合以促进域事件和/或复合应用程序架构。
jeremy miller 在事件聚合器上有一篇很棒的帖子:http://codebetter.com/blogs/jeremy.miller/archive/2009/07/21/braindump-on-the-event-aggregator-pattern.aspx
我使用他的帖子创建了我的事件聚合器,我将它放入我的 winforms/手持应用程序的基于消息传递的架构中:http://www.lostechies.com/blogs/derickbailey/archive/2009/12/22/understanding-the-application-controller-through-object-messaging-patterns.aspx
【讨论】:
我认为通常没有真正的理由不应该使用 C# 委托模型来实现观察者模式。但是,在 .Net 4 中,他们添加了IObserver<T> 和IObservable<T> 接口来实现基于推送的通知系统。所以,我想这是您希望使用接口而不是基于事件的模型的情况之一。
【讨论】:
我同意 .NET 的事件处理程序可以满足您对观察者模式的大部分需求。但是,您需要注意几个接口,尤其是 Silverlight 和 WPF。它们是 INotifyPropertyChanged 和 INotifyCollectionChanged。这些规定了 Silverlight 和 WPF 期望用于数据绑定的特定模式。此外,还有一个实现 INotifyCollectionChanged 的 ObservableCollection 类;这在构建 Silverlight 和 WPF 接口时省去了很多麻烦。
【讨论】:
我同意经典的观察者设计模式在 C# 中得到了极大的简化。我认为可能存在使用经典实现“更安全”的案例。想到的事情是多线程和公共 API。我认为如果您采用经典方式,单元测试有时可能会更容易。但是,就像您提到的那样,现在使用 C# 委托有一个更简单的快捷方式。抱歉,对于何时必须使用经典模式,我没有明确的答案。
【讨论】:
我会看看这个帖子:
我特别喜欢 Jon Skeet 的一条评论:
当然。这有点像在问,“我应该实现迭代器模式还是使用 foreach 和 IEnumerable?”
这是对这个说得很好的答案的回应:
嗯,事件可以用来实现观察者模式。事实上,使用事件可以看作是观察者模式恕我直言的另一种实现。
但选择的答案相当不错,适用。
【讨论】: