在C#中,观察者模式不是已经使用事件实现了吗?

33

在阅读了《Head First设计模式》一书并使用了许多其他设计模式后,我试图理解观察者模式。不过,在.NET Framework中使用事件已经实现了这个模式,是吗?

8个回答

26

是的,确实如此。观察者模式也被称为发布/订阅模式,这正是事件允许您执行的操作。


1
对于这个问题的稍微不同的答案,请参见https://dev59.com/lnNA5IYBdhLWcg3wS7sm - kmote

22

我认为Anders Heljsberg的意图是通过在C#中使用事件,将观察者模式变成一种一流的语言特性,这取决于他在Delphi方面的经验。在Software Engineering Radio上的一次出色访谈中,Anders明确了这一点和其他设计意图。


8

是的,它们是完全一样的。

请注意:如果你真的想理解事件,我建议你学习观察者模式并自己实现一段时间。一旦你完全理解了它,停止自己实现并使用专业和文档完备的实现,除非你有真正需要做其他事情。


4

是的,但是显式编写观察者模式而不使用委托和事件可以使您的代码更容易调试。

考虑以下区别:

public void NotifyObservers()
{
    foreach(Product product in ProductList)
    {
        if (product is IProductObserver)
        {
               product.Update(this)
        }
    }
}

这里非常清楚地说明了列表中的哪些产品会收到更改通知。调试时,您可以检查ProductList...

使用委托和事件时,要找出有多少“委托”实际上已经“订阅”来处理事件可能会更加繁琐。


我不喜欢鼓励开发者重新实现而不是重复使用的想法。 - Jay Bazuzi
2
你能详细说明一下吗?我的意思是,在这两种情况下,开发人员都必须实现该模式。我之所以将其作为一个明确的示例,基本上是因为我同意Dinah的观点,即如果您真的想了解观察者模式,最好先自己构建它,然后再去参加事件。 - Hace

4

没错,事件是观察者模式的一种实现。然而,我曾阅读过一些讨论,有些人仍然编写自己的事件,以便更灵活,或者只是为了避免事件触发语法。


0

微软本身指出,使用事件和委托是应用观察者模式的C#方式。 通过使用一些基本的命名约定来命名事件和委托,他们将自己的模式命名为"事件模式",它完全可以提供比经典的观察者模式更多的优势。

"事件模式"在MSDN库中的"探索观察者设计模式"文章中有描述。

参考MSDN文章

基于事件和委托,FCL 在很大程度上使用观察者模式。FCL 的设计者充分认识到这种模式的内在优势,并将其应用于框架中的用户界面和非 UI 特定功能。然而,这种使用是基于观察者模式的轻微变体,由框架团队称为事件模式。通常,该模式通过对委托、事件和与事件通知过程相关的方法的正式命名约定来表达。Microsoft 建议所有使用事件和委托的应用程序和框架采用此模式,尽管 CLR 或标准编译器中没有强制执行。
通过对观察者模式的研究,可以明显看出,无论对象的功能是 UI 还是其他,该模式都提供了一种理想的机制来确保应用程序中对象之间的清晰边界。虽然通过回调(使用 IObserver 和 IObservable 接口)相当简单实现,但 CLR 中的委托和事件概念处理了大部分“重活”,并降低了主题和观察者之间的耦合程度。

0

大多数现代编程语言都原生支持一些设计模式。有人认为,语言的优点越多,它们就越能够在不需要显式实现的情况下本地支持更多模式,而 Lisp 在这方面表现出色。Jeff 也对此有自己的看法


-1
不,它们实现了相同的意图,但它们是不同的。 我会说观察者模式是一种过度设计的hack,为了实现你可以通过函数式编程轻松实现的东西,而.NET事件使用函数式编程来实现相同的目标。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接