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

时间:2013-03-24 03:36:15

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

Observer Pattern Publish/Subscribe Data Binding 之间有什么区别?< / p>

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

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

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

4 个答案:

答案 0 :(得分:145)

Observer / Observable和发布者/订阅者模式之间存在两个主要差异:

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

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

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

答案 1 :(得分:128)

以下是对三者的看法:

数据绑定

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

Observer,或Observable / Observer

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

发布/订阅

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

数据绑定,Redux

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

数据绑定重做Redux

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

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

答案 2 :(得分:18)

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

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

  

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

     

Observer pattern

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

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

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

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

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

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

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

有关详细信息,请参阅this pubsub example

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

答案 3 :(得分:9)

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

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

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

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

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

我希望这有帮助!