观察者模式与事件驱动方法的区别

时间:2011-06-22 12:05:43

标签: events design-patterns observer-pattern

我总是发现观察者模式几乎与通常的事件驱动方法类似。实际上,我几乎相信它们实际上只是指同一件事的不同名称。他们都使用类似的概念来作为一个监听器,甚至在实现中,它们几乎是相同的东西,那就是有一个回调方法/函数来执行一个动作。这至少在Java中。

在其他语言中说Actionscript / Flex,这些事件更加用户友好,并且可能看起来不仅仅是观察者模式定义。但是,这些概念听起来仍然相同。

但这是真的吗?观察者模式是否与通常的事件驱动编程风格相同?

12 个答案:

答案 0 :(得分:34)

观察者模式是一个非常特殊的实例。事件驱动可能意味着什么。在大多数观察者模式实现中,观察者是观察观察者的对象。当观察者改变时,调用观察者的方法。严格来说,这不是一个“事件”。这意味着:对观察者采取各种不同的行动,通常会导致在观察者中调用不同的方法。语法“什么”改变了在方法中。 在事件驱动系统中,您基本上有一个消费对象/方法以及事件中已更改或发生的消息。这可以是任何东西,并不限于观察某事的想法!这意味着:在事件驱动系统中,您可以通过添加新的事件类型来获得新的语义。在Observer模式中,您通常通过向Observer类添加方法来添加语义。但是:没有人阻止你将Observer实现为ChangeEvents的特殊池。

答案 1 :(得分:22)

当发布者或主题发生状态更改时,

  • 事件驱动架构(是一种消息驱动架构),负责异步传递消息给订阅者。

  • 观察者模式(是一种软件设计模式),负责命令订阅者同步执行某些操作。

答案 2 :(得分:11)

  

事件驱动编程是定义范例的术语。而   可观察模式是制作应用程序的设计解决方案   事件驱动的。

干杯!

答案 3 :(得分:10)

差异No.1可能是,Event-Systems总是有一个eventdispatchthread,它将观察者与其观察者分离,因此事件可能无法立即到达观察者。虽然real observables直接调用观察者方法,但事件驱动的observables将其事件放入事件队列中。然后,EDT将这些事件传递给注册的听众。

答案 4 :(得分:1)

我已经搜索过同样的问题了。 对于这个主题,我从Angel O' Sphere上找到了#34;什么语义"并指出Spacerat on" Dispatcher"做帮助。

这两点是我的理解,将Even-Driver与观察者模式区分开来。至少从规范的解释,"观察者模式"通常代表一次"主题"已经改变了" Dispatching"通过调用订阅者或监听者提供的接口来实现。而对于事件驱动,在"主题和"观察者"之间总会存在另一层。要么叫'#34; Dispatcher"或使用"事件队列"。这提供了"延迟"处理以降低CPU使用率并且还提供调用不同接口的某些功能取决于不同的事件类型。

答案 5 :(得分:1)

两者的基本区别在于耦合和同步行为。如果我们坚持使用观察者模式,我们说只有一个信号源并且它将是同步的,而另一方面,对于事件,我们将双方分离以独立工作,同时考虑拥有多个来源的可能性。将来的事件没有任何代码更改。事件帮助我们接受与设计异步。所有Reactive编程库都为事件驱动设计提供了非常好的支持。

答案 6 :(得分:1)

我试着很简单,因为这也帮了我一次。

想想观察者和观察者。相反,observable标记了一个setChanged,观察者从observable请求改变了什么,而observable则向对象(事件携带状态)广播一个关于观察者变化的所有相关信息。所以在Observer和Observable之间实际上还有一个实例。

http://www.grahambrooks.com/event-driven-architecture/patterns/stateful-event-pattern/

答案 7 :(得分:1)

从这个问题,这个hackernoon article和我自己的经验的多个答案中得出的结论是,在我看来,观察者模式与事件驱动(例如,Pub-Sub)架构之间的主要区别在于:

在观察者模式中,观察者 ed 保留对其观察者成员的引用。

在Pub-Sub中,广播者不知道其监听者是谁。 (或者,即使有人在监听。)监听器可能希望广播者提供一些数据,但不知道事件的确切来源。也许它来自多个类或远程系统。也许不吧。广播者或侦听器都没有关系。

现在,并不是说这些东西有很大的不同。另外,有些实现的行为类似或两者相同。

例如,wisper rubygem允许您根据需要充当观察者模式或发布订阅模式。如果愿意,您甚至可以将两者一起使用。

答案 8 :(得分:1)

关于观察者模式的一大优点是安全性。当被观察者对象内发生代码更改时,所有观察者都必须实现新的更改。如果我们改用事件,则事件侦听器将不会对新事件的实现做出反应。换句话说,观察者指示事件必须由观察者处理。

在我的一个项目中,我遇到了一种情况,在这种情况下,一个被观察者的物体被破坏了,因此需要通知观察者。我唯一要做的就是将通知添加为所有观察员的要求,并在观察员被摧毁之前触发事件。这样做的好处是,只有在所有观察者都为新创建的事件实现了处理程序的情况下,代码才会编译,因此您不太可能忘记更改其中的一些事件。就我而言,我有很多可能的观察者,很高兴知道我可以进行更改而不会产生一些或更多隐藏的错误。

这些特质使观察者模式的灵活性不如简单地引发事件,而是让观察者自己决定。但是,在使用事件时,要提防那些隐藏在拐角处的伟大的意大利面怪物,并且只有在截止日期临近时才会出现。像我一样,你们中可能有不止一个人遇到这个丑陋的野兽不止一次。

换句话说,要尽可能务实,仍然使用正确的工具来完成工作。这意味着在需要灵活性时使用事件,在需要控制时使用观察者。

答案 9 :(得分:0)

是的,它们主要是相同的。

事件类似于某些语言的“内置”观察者模式模板。

因此,您不会真正用支持事件的语言实现观察者模式,因为它们已经提供了您正在寻找的内容。
另一方面,您可以使用观察者模式在缺少事件的语言中编写事件驱动。

答案 10 :(得分:0)

来自Wikipedia

  

观察者模式是一个软件设计模式,其中一个对象,   称为主题,维护其受抚养人名单,称为   观察者,并自动通知他们任何状态变化,   通常通过调用他们的方法之一。

     

它主要用于实现分布式事件处理系统   "事件驱动"软件。大多数现代语言,如Java和C#   内置"事件"实现观察者模式的构造   组件,便于编程和短代码。

观察者模式更具抽象性和理论性。事件是一个(通常是内置的)实现,但是如Angel的回答中所述,事件往往能够在除了观察者严格定义的其他几种情况下使用图案。

答案 11 :(得分:0)

事件驱动是一种软件范例或编写代码的样式,其中对象使用事件进行通信。某些语言(例如C#)对事件具有本机支持。您可以让一个对象引发另一个对象侦听的事件。观察者模式是获得相同结果的另一种方法。