观察者,发布/订阅和数据绑定之间的区别


163

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

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

我已经相信数据绑定是一个通用术语,并且有多种实现它的方式,例如观察者模式或发布/订阅模式。通过观察者模式,观察者更新其观察者。使用发布/订阅,0个发布者可以发布某些类别的消息,0个订阅者可以订阅某些类别的消息。

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


我发现了另一个:脏检查,这是Angular.js的工作。此处的更多信息:stackoverflow.com/questions/9682092/databinding-in-angularjs
Jess 2014年

Answers:


143

这是我对三个方面的看法:

数据绑定

本质上,从根本上讲,这仅意味着“对象Y上的属性X的值在语义上绑定到对象B上的属性A的值。不对Y如何知道或馈送对象B的更改进行任何假设。

观察者或可观察/观察者

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

发布/订阅

Observable / Observer模式的另一个名称(也许具有更多的“广播”语义),通常意味着更具“动态”的味道-观察者可以订阅或取消订阅通知,而一个可观察者可以“喊叫”多个观察者。在.NET中,由于事件是MulticastDelegate的一种形式,因此可以使用标准事件,因此可以支持将事件传递给多个订阅者,也支持取消订阅。在某些情况下,Pub / Sub的含义略有不同,通常在事件和事件方之间包含更多的“匿名性”,这可以通过任意数量的抽象来促进,通常涉及一些了解所有内容的“中间人”(例如消息队列)政党,但各个政党彼此都不认识。

数据绑定,Redux

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

数据绑定重做

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

  • 启动一个后台线程,该线程不断检查对象的绑定属性。
  • 如果该线程检测到自上次检查以来属性的值已更改,则将值复制到绑定的项目。

非常感谢您的回答,并尝试实现不同的数据绑定想法。
杰西

@jessemon嘿,没问题;观察者模式绝对是我所知道的“绝对最佳”方法,但是我那可怕的小例子也将“进行数据绑定”,尽管这是一种混乱且效率低下的方式。
JerKimball 2013年

7
老实说,我厌倦了听到“发布者/订阅者也称为观察者模式”,它们根本不是一回事。发布/ 订阅是事件系统,观察者模式使用事件系统根据对象的更改自动发布事件。如果您在每次更改对象时都手动发出事件,那么您就不会使用观察者模式。
英国电信

154

观察者/可观察者模式与发布者/订阅者模式之间有两个主要区别:

  1. Observer / Observable模式通常以同步方式实现,即,当某个事件发生时,observable调用其所有观察者的适当方法。的发行者/订户图案在一个实施大多异步方式(使用消息队列)。

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

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


7
我正在阅读O'Reilly的JavaScript Web应用程序shop.oreilly.com/product/0636920018421.do)。在第2章中,Alex实现了一个pub/sub使用JS事件。这是一种回调类型的实现,但它是一个同步示例。
杰西

5
我还没有读过这本书,但是如果它是使用JS“事件”实现的,那么它将是异步的,因为事件在定义上是异步的。
Param

3
嗨,杰西,你当然是对的。没有这些条款😊没有标准的定义
帕拉姆

14
通常,一个可观察对象具有一个观察者列表(它在该列表上进行迭代以将事件发送给所有观察者)。发布者通常只知道发布事件/消息的队列。它不知道有多少消费者订阅了该队列。
Param

7
对我来说,这是两者之间的关键区别:此外,在观察者模式中,观察者也知道可观察的事物。而在发布/订阅中,发布者和消费者都不需要彼此了解。他们只是在消息队列的帮助下进行通信。好答案!
maryisdead 2015年

23

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

需要注意的一件事是:这些模式的目标是试图使代码脱钩。

观察者是一种设计模式,其中一个对象(称为主题)维护一个依赖于它的对象(观察者)的列表,并自动将状态的任何更改通知它们。

观察者模式

这意味着observable object有一个列表,其中保留了所有列表observers(通常是函数)。并可以遍历此列表并在感觉合适的时候调用这些函数。

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

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

但是Cons is Observables仅维护一个数组以保留观察者(在示例中,该数组为observersList)。

它没有区别更新的触发方式,因为它只有一个notify function,它将触发存储在该数组中的所有函数。

如果我们想基于不同的事件将观察者处理程序分组。我们只需要修改observersList一个Object

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

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

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


好吧,这是一个更好,简洁和清晰的答案。:)
CoderX

在较高的层次上,我一直说pub sub是观察者模式,但是所有东西都有不同的风格。
冷面

9

我同意您对这两种模式的结论,不过,对我来说,当我处于同一过程中时,我使用Observable;在过程间场景中,我使用Pub / Sub,其中各方仅知道公共渠道,而各方不知道。

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

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

“企业集成模式:设计,构建和部署消息解决方案”-http : //www.addison-wesley.de/9780321200686.html

本书包含许多关于如何在进程或类之间发送消息的想法,即使在进程内通信任务中也可以使用它们(它帮助我以更松耦合的方式进行编程)。

我希望这有帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.