关于模型视图控制器:Observer,Pub / Sub和Data Binding之间的区别

Difference between Observer, Pub/Sub, and Data Binding

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

我在堆栈溢出上搜索了一下,没有找到任何好的答案。

我相信数据绑定是一个通用术语,有不同的实现方法,例如观察者模式或发布/子模式。通过观察者模式,观察者更新其观察者。使用pub/sub,0-许多发布者可以发布特定类的消息,0-许多订阅者可以订阅特定类的消息。

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


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

  • 观察者/可观察模式主要以同步方式实现,即,当发生某些事件时,可观察者调用其所有观察者的适当方法。发布服务器/订阅服务器模式主要以异步方式实现(使用消息队列)。

  • 在观察者/可观察的模式中,观察者知道可观察的。然而,在发布者/订阅者中,发布者和订阅者不需要相互了解。它们只是通过消息队列的帮助进行通信。

  • 正如您正确提到的,数据绑定是一个通用术语,可以使用observer/observable或publisher/subscriber方法来实现。数据是发布服务器/订阅服务器。


    这是我对这三个问题的看法:

    数据绑定

    本质上,在核心,这仅仅意味着"对象y上的属性x的值在语义上与对象b上的属性a的值绑定在一起。没有假设y是如何知道或是如何被馈送对象b上的更改的。

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

    一种设计模式,通过这种模式,一个对象被赋予通知其他特定事件的能力——通常使用实际事件来完成,这些事件类似于对象中具有特定函数/方法形状的槽。Observable是提供通知的人,观察者接收这些通知。在.NET中,Observable可以公开一个事件,观察者用一个"事件处理程序"形状的钩子订阅该事件。没有对通知发生的具体机制,也没有对一个观察者可以通知的观察者数量作出假设。

    发布/订阅

    可观察/观察模式的另一个名称(可能具有更多的"广播"语义),通常意味着一种更"动态"的风格-观察者可以订阅或取消订阅通知,一个可观察者可以"呼喊"给多个观察者。在.NET中,可以为此使用标准事件,因为事件是多播委托的一种形式,因此可以支持将事件传递给多个订阅服务器,也可以支持取消订阅。pub/sub在某些上下文中的含义稍有不同,通常在事件和事件之间涉及更多的"匿名性",这可以通过任何数量的抽象来实现,通常涉及一些了解所有方的"中间人"(例如消息队列),但各个方不了解彼此。

    数据绑定,redux

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

    数据绑定重新还原

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

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


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

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

    The Observer is a design pattern where an object (known as a subject) maintains a list of objects depending on it (observers), automatically notifying them of any changes to state.

    Observer pattern

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

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

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

    但是缺点是可以观察到的,只保留一个数组来保存观察者(在示例中,数组是observersList)。

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

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

    1
    2
    3
    4
    var events = {
       "event1": [handler1, handler2],
       "event2": [handler3]
    }

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

    人们称这种变异为pub/sub。因此,您可以根据您发布的events触发不同的函数。


    我同意你关于这两种模式的结论,不过,对我来说,当我处于同一个过程中时,我使用Observable,并且在进程间场景中使用pub/sub,在这些场景中,所有参与方只知道公共渠道,而不知道参与方。

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

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

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

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

    希望这有帮助!