178

观察者模式发布/订阅数据绑定有什么区别?

我在 Stack Overflow 上搜索了一下,没有找到任何好的答案。

我开始相信数据绑定是一个通用术语,并且有不同的实现方式,例如观察者模式或发布/订阅模式。使用观察者模式,可观察者更新其观察者。使用 Pub/Sub,0-many 发布者可以发布某些类的消息,0-many 订阅者可以订阅某些类的消息。

还有其他实现“数据绑定”的模式吗?

4

4 回答 4

175

Observer/Observable 和 Publisher/Subscriber 模式之间有两个主要区别:

  1. Observer/Observable模式大多以同步方式实现,即当某个事件发生时,observable 调用其所有观察者的适当方法。发布者/订阅者模式主要以异步方式实现(使用消息队列)。

  2. Observer/Observable模式中,观察者知道 observable。而在Publisher/Subscriber中,发布者和订阅者不需要相互认识。他们只是在消息队列的帮助下进行通信。

正如您正确提到的,数据绑定是一个通用术语,可以使用 Observer/Observable 或 Publisher/Subscriber 方法来实现。数据是发布者/可观察者。

于 2013-03-24T07:25:38.420 回答
154

以下是我对三者的看法:

数据绑定

从本质上讲,这只是意味着“对象 Y 上的属性 X 的值在语义上绑定到对象 B 上的属性 A 的值。没有假设 Y 如何知道或接受对象 B 上的更改。

观察者,或可观察者/观察者

一种设计模式,通过该设计模式,对象具有通知其他特定事件的能力 - 通常使用实际事件完成,这些事件有点像对象中具有特定功能/方法形状的插槽。可观察对象是提供通知的对象,观察者接收这些通知。在 .net 中,observable 可以公开一个事件,并且观察者使用“事件处理程序”形状的钩子订阅该事件。没有关于通知发生的具体机制,也没有关于一个 observable 可以通知的观察者的数量做任何假设。

发布/订阅

Observable/Observer 模式的另一个名称(可能具有更多“广播”语义),这通常意味着更“动态”的风格 - 观察者可以订阅或取消订阅通知,一个可观察者可以向多个观察者“大喊”。在 .NET 中,可以为此使用标准事件,因为事件是 MulticastDelegate 的一种形式,因此可以支持将事件传递给多个订阅者,并且还支持取消订阅。Pub/Sub 在某些上下文中的含义略有不同,通常在 event 和 eventer 之间涉及更多的“匿名性”,这可以通过任意数量的抽象来促进,通常涉及一些知道一切的“中间人”(例如消息队列)各方,但个别各方不知道对方。

数据绑定,Redux

在许多“类似 MVC”的模式中,可观察对象公开了某种方式的“属性更改通知”,其中还包含有关更改的特定属性的信息。观察者是隐式的,通常由框架创建,并通过一些绑定语法订阅这些通知以明确标识对象和属性,并且“事件处理程序”只是将新值复制过来,可能会触发任何更新或刷新逻辑。

数据绑定重新 Redux

数据绑定的替代实现?好吧,这是一个愚蠢的:

  • 启动一个后台线程,不断检查对象的绑定属性。
  • 如果该线程检测到自上次检查后属性的值发生了变化,则将该值复制到绑定项。
于 2013-03-24T07:42:18.823 回答
34

我有点好笑,这里的所有答案都试图解释 Observer 和 Pub/Sub 模式之间的细微差别,而没有给出任何具体的例子。我敢打赌,大多数读者仍然不知道如何通过阅读一个是同步的而另一个是异步的来实现每一个。

需要注意的一点是:这些模式的目标是尝试解耦代码

观察者是一种设计模式,其中一个对象(称为主体)根据它(观察者)维护一个对象列表,自动通知它们状态的任何变化。

观察者模式

这意味着 anobservable object有一个列表,它保存所有的observers(通常是函数)。并且可以在感觉好的时候遍历这个列表并调用这些函数。

有关详细信息,请参阅此观察者模式示例。

当您想要侦听对象上的任何数据更改并相应地更新其他 UI 视图时,此模式非常有用。

但是 Cons 是Observables 只维护一个数组来保存观察者 (在示例中,数组是observersList)。

它不会区分更新是如何触发的,因为它只有一个notify function,它会触发存储在该数组中的所有函数。

如果我们想根据不同的事件对观察者处理程序进行分组。我们只需要将其修改observersListObject类似

var events = {
    "event1": [handler1, handler2],
    "event2": [handler3]
}

有关详细信息,请参阅此 pubsub 示例

人们称这种变化为pub/sub。因此,您可以根据events发布的内容触发不同的功能。

于 2016-07-08T21:15:44.037 回答
12

我同意你关于这两种模式的结论,但是,对我来说,我在同一个进程中使用 Observable 并且我在进程间场景中使用 Pub/Sub,其中各方只知道公共渠道而不知道各方.

我不知道其他模式,或者让我这样说,我从来不需要其他模式来完成这项任务。甚至大多数 MVC 框架和数据绑定实现通常在内部使用观察者概念。

如果您对进程间通信感兴趣,我建议您:

“企业集成模式:设计、构建和部署消息传递解决方案” - https://www.enterpriseintegrationpatterns.com/

这本书包含很多关于如何在进程或类之间发送消息的想法,这些想法甚至可以用于进程内通信任务(它帮助我以更松散耦合的方式进行编程)。

我希望这有帮助!

于 2013-03-26T10:29:00.230 回答