观察者设计模式 vs “监听器”

167

在我看来,GoF中描述的观察者设计模式与各种工具包中的监听器是相同的东西。这些概念是否有区别?或者说监听器和观察者真的是同一件事情吗。

(我不寻找任何特定的计算机语言实现,我只想从设计的角度了解它们之间的区别(如果有)。是的,我知道在SO上有几个类似问题的答案,但它们都根植于特定语言的特定问题--我正在寻找的是一个设计答案,而不是语言答案。)


21
在前者中,一段代码观察另一段代码的动作,而在后者中,一段代码监听另一段代码是否有任何噪音。 - nate c
3
GOF代表什么? - dekaru
7
“Gang of Four”指的是Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides这四位计算机科学家,他们于1994年出版了一本著名的书籍《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software),该书介绍了23种常见的软件设计模式。这些设计模式是在实践中被证明有用的,并且现在已经成为了软件工程领域中的经典之作。 - bitsoflogic
哈哈,我本来想问什么是SOF。 - bigstones
@bigstones -- 很好的观点,已修复! - JohnnyLambada
3个回答

69
无论“listener”一词是否涉及观察者模式,都取决于上下文。例如,Java Swing的“事件监听器”是观察者模式的一部分实现,而.NET的“跟踪监听器”则不是。
框架作者通常会为参与给定模式实现的组件分配不同的名称,但在讨论模式本身时通常使用官方模式名称。
关于设计,给定模式的实现通常会受到所使用的语言和平台的影响。因此,在给定框架中实现观察者模式的特定实现(可能会使用术语“listener”来描述ConcreteObserver的角色)可能与《设计模式》书中描述的略有不同。

你提到了.NET中的“Trace Listeners”不是观察者模式的一部分。那么它们是什么? - Edwin Diaz
1
我不确定你是在问它们的目的还是属于哪种模式。.Net跟踪侦听器只是可插入的接收器,用于写入一系列日志消息(例如,写入控制台、写入文件、写入事件日志等)。就模式而言,尽管整个.Net跟踪功能采用了几种模式(插件、迭代器),但循环遍历一组符合同一接口的对象只是普通的多态性。TraceListener本身并不关心被观察对象的状态变化,所以这不完全是观察者模式。 - Derek Greer

34

在Gamma等人所著的《设计模式》一书中,观察者有一个双向性质。

他们对观察者的描述中,其中一个具体观察者可能会向其主题发出信号。主题(持有所有具体观察者的列表)随后通知它的列表。包括主要驱动程序在内的所有具体观察者都会作出适当反应。

常见的监听器实现似乎都是对外部事件做出反应。

因此,我认为监听器是观察者的一种更特殊的情况。

命名示例

如果您只想知道要使用什么名称,您可能希望将“listener”用于简单的内容,“observer”用于超出回调范围的任何复杂内容。

我的意思是字面上,一个人可以用许多方法“观察”,但一个人只能“听取”某物发出的外部噪音(如回调、通知等)。


3
在GoF的观察者模式中,主题会通知观察者其自身状态的变化。因此,“状态观察者”实际上是该模式的更具描述性的名称。正如您所描述的那样,它还允许观察者对主题进行操作。因此,尽管监听器在这方面似乎不太一般,但我认为它们在另一方面也更加一般,因为它们对任何类型的事件都会做出反应,而不仅仅是它们感兴趣的主题状态变化。 - Piovezan

3
一个监听器可以是观察者模式的实现。监听器基本上在等待给定对象上发生事件,这正是观察者所做的事情。
我知道你不需要特定语言的答案,但以抽象的方式讨论这些内容有点困难。因此,如果我要在.NET中研究这个问题,我会倾向于打开一个包含.NET反射器中的监听器的程序集,这将允许我反汇编程序集并根据设计模式检查其逻辑。

1
“监听器本质上是在等待给定对象上发生事件,这就是观察者所做的事情。”不完全正确,根据《设计模式》一书,观察者并不等待任何类型的事件,而是等待主题状态的改变,然后观察者可以查询(拉取)状态。也许“状态观察者”是该模式的更精确名称。 - Piovezan

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