【问题标题】:Difference between Observer, Pub/Sub, and Data Binding观察者、发布/订阅和数据绑定之间的区别
【发布时间】:2013-03-13 18:13:43
【问题描述】:

Observer PatternPublish/SubscribeData Binding有什么区别?

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

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

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

【问题讨论】:

标签: model-view-controller design-patterns data-binding observer-pattern publish-subscribe


【解决方案1】:

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

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

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

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

【讨论】:

  • 我正在阅读 O'Reilly (shop.oreilly.com/product/0636920018421.do) 的 JavaScript Web Applications。在第 2 章中,Alex 使用 JS 事件实现了 pub/sub。它是一个回调类型的实现,但它是一个同步的例子。
  • 我没看过这本书,但是如果它是使用JS“事件”实现的,它会是异步的,因为从定义上来说事件是异步的。
  • 嗨,杰斯,你当然是对的。这些术语没有标准定义?
  • 通常一个 observable 有一个观察者列表(它遍历这个列表以向所有观察者发送事件)。发布者通常只知道它发布其事件/消息的队列。它不知道有多少消费者订阅了该队列。
  • 对我来说,这是两者之间的关键区别:另外,在观察者模式中,观察者知道可观察对象。而在 Pub/Sub 中,发布者和消费者都不需要相互了解。他们只是在消息队列的帮助下进行通信。很好的答案!
【解决方案2】:

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

数据绑定

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

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

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

发布/订阅

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

数据绑定,Redux

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

数据绑定重新 Redux

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

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

【讨论】:

  • 非常感谢您的回答并尝试实现不同的数据绑定理念。
  • @jessemon heh,没问题;观察者模式绝对是我所知道的“抽象最佳”方法,但我可怕的小例子也会“进行数据绑定”,尽管是以一种混乱且低效的方式。
  • 老实说,我厌倦了听到“pub/sub aka 观察者模式”,它们根本不是一回事。 Pub/sub 是一个事件系统,观察者模式使用一个事件系统在对象发生变化时自动发布事件。如果您在更改对象时手动发出事件,则说明您没有使用观察者模式。
【解决方案3】:

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

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

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

Observer pattern

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

详情请参阅this observer pattern 示例。

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

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

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

如果我们想根据不同的事件对观察者处理程序进行分组。我们只需要将 observersList 修改为 Object 即可

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

详情请参阅this pubsub example

人们将此变体称为pub/sub。所以你可以根据你发布的events触发不同的功能。

【讨论】:

  • 嗯,这是一个更好、更简洁、更清晰的答案。 :)
  • 在高层次上,我一直说 pub sub 是观察者模式,但它具有不同的风格。
【解决方案4】:

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

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

如果你对进程间通信感兴趣,我推荐你:

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

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

我希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2017-06-16
    • 2015-02-24
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 2019-07-14
    • 1970-01-01
    • 2017-09-02
    相关资源
    最近更新 更多