Observer,Pub / Sub和Data Binding之间的区别

问题描述 投票:147回答:4

Observer PatternPublish/SubscribeData Binding有什么区别?

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

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

是否有其他实施“数据绑定”的模式?

model-view-controller design-patterns data-binding observer-pattern publish-subscribe
4个回答
129
投票

以下是我对三者的看法:

Data Binding

本质上,在核心,这只意味着“对象Y上的属性X的值在语义上与对象B上的属性A的值绑定。没有假设Y如何知道或对对象B进行更改。

Observer, or Observable/Observer

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

Pub/Sub

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

Data Binding, Redux

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

Data binding re Redux

数据绑定的另一种实现方式?好的,这是一个愚蠢的:

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

146
投票

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

  1. Observer / Observable模式主要以同步方式实现,即当某些事件发生时,observable调用其所有观察者的适当方法。发布者/订阅者模式主要以异步方式实现(使用消息队列)。
  2. 在Observer / Observable模式中,观察者知道可观察的。然而,在发布者/订阅者中,发布者和订阅者不需要彼此了解。他们只是在消息队列的帮助下进行通信。

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


18
投票

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

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

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

Observer pattern

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

有关详细信息,请参阅this observer pattern示例。

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

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

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

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

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

请参阅this pubsub example了解详情。

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


9
投票

我同意你关于这两种模式的结论,但是,对我来说,当我处于相同的过程中时我使用Observable并且我在进程间场景中使用Pub / Sub,其中所有方只知道公共信道但不知道各方。

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

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

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

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

我希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.