观察者模式和事件驱动方法之间的区别
我总是发现观察者模式与通常的事件驱动方法几乎相似。事实上,我几乎相信它们实际上只是指同一事物的不同名称。它们都使用类似的概念来作为监听器,甚至在实现中,它们几乎是相同的东西,那就是有一个回调方法/函数来执行操作。至少在 Java 中是这样。
在其他语言(例如 Actionscript/Flex)中,事件对用户更加友好,并且看起来它所做的不仅仅是观察者模式定义的功能。但这些概念听起来还是一样的。
但这真的是真的吗?观察者模式与通常的事件驱动编程风格是一样的吗?
I always found the Observer Pattern almost similar to the usual event-driven approach. Actually, I have almost believed that they are actually just different names referring to the same thing. They both use similar concepts to have something as a listener and even in the implementation, they are almost the same thing, that's to have a callback method/function to carry out an action. This is at least in Java.
In other languages say Actionscript/Flex, the events are more user-friendly and may look like it does more than just the observer pattern defines. But still, the concepts sound the same.
But is this really true? Is the Observer Pattern the same thing as the usual event-driven programming style?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
观察者模式是一个非常特殊的实例。事件驱动可以意味着任何事情。在大多数观察者模式实现中,观察者是观察被观察者的对象。当观察者改变时,调用观察者的方法。严格来说,这不是一个“事件”。这意味着:观察者的各种不同动作,通常会导致观察者调用不同的方法。语义“什么”发生了变化是在方法中。
在事件驱动系统中,您基本上有一个消费对象/方法,并且事件中包含更改或发生的消息。这可以是任何东西,并且不限于观察某事的想法!这意味着:在事件驱动系统中,您可以通过添加新的事件类型来获得新的语义。在观察者模式中,您通常通过向观察者类添加方法来添加语义。但是:没有人会阻止您实现观察者作为 ChangeEvents 的特殊侦听器。
The Observer Pattern is a very special instance. Event-Driven can mean anything. In most Observer Pattern implementations the Observer is an object watching the observee. When the observee is changed, a method of the observer is called. Strictly speaking this is not an "Event". That means: various different actions on the observee, usually lead to the call of different methods in the observer. The semantics "what" got changed is in the method.
In Event Driven Systems, you basically have one consuming object/method and the message what was changed or what happend is in the Event. That can be anything and is not limitd to the idea of observing something! That means: in an Event Driven System you get new semantics by adding new Event types. In an Observer Pattern you usually add semantics by adding a method to the Observer class. HOWEVER: no one is preventing you to implement an Observer as a special listern to ChangeEvents.
当发布者或主题发生状态更改时,
事件驱动架构(消息驱动架构)负责异步传递消息给订阅者。
观察者模式(是一种软件设计模式),负责命令订阅者同步和异步地执行某些操作。
When there is a state change at the Publisher or Subject,
Event Driven Architecture (is a message-driven architecture), responsible to deliver message to the Subscriber, asynchronously.
Observer Pattern (is a software design pattern), responsible to command the Subscriber to do something, synchronously and asynchronously.
干杯!
Cheers!
综合这个问题的多个答案,这篇hackernoon文章,以及我自己的根据我的经验,观察者模式和事件驱动(例如 Pub-Sub)架构之间的主要区别是:
在观察者模式中,被观察者被观察者维护对其观察者观察员的引用。
而在 Pub-Sub 中,广播者不知道其听众是谁。 (或者即使有人在那里监听。)监听器可能期望来自广播者的一些数据,但不知道事件到底来自哪里。也许它来自多个类或远程系统。也许不是。这对广播者或听众来说并不重要。
现在,这并不是说这些事情有很大不同。此外,还有一些实现的行为类似于其中之一或两者。
例如,wisper rubygem 允许您像观察者模式或发布-订阅模式一样运行,具体取决于你的需要。如果您愿意,您甚至可以将两者一起使用。
Synthesizing from multiple answers in this question, this hackernoon article, and my own experience, the key difference between the Observer Pattern and Event-Driven (Pub-Sub, say) Architecture is, in my mind, this:
In the Observer Pattern, the Observed maintains references to its Observers.
Whereas in Pub-Sub, the Broadcaster has no idea who its Listener(s) are. (Or even if anyone is there to listen.) The Listener may expect some data from the Broadcaster, but has no idea exactly where the event comes from. Maybe it comes from multiple classes or remote systems. Maybe not. It doesn't matter to either the Broadcaster or Listener.
Now, that's not to say these things are very different. Also, there are implementations that behave like either or both.
For example, the wisper rubygem allows you to act like either an Observer pattern or a Pub-Sub pattern depending on your need. You can even use both together if you like.
差异之一可能是,事件系统总是有一个事件调度线程,它将可观察量与其观察者解耦,因此事件可能不会立即到达观察者。虽然真正的可观察对象直接调用观察者方法,但事件驱动的可观察对象将其事件放入事件队列中。然后 EDT 将这些事件传递给注册的侦听器。
The diffrence No.1 may be, that Event-Systems always have an eventdispatchthread which decouples observables from its observers so events may not reach the observers immediatly. While real observables call observer methods directly, event driven observables drop their events into an eventqueue. Then the EDT deliveres those events to registered listeners.
是的,它们基本上是相同的。
事件类似于某些语言的“内置”观察者模式模板。
因此,您不会真正用支持事件的语言实现观察者模式,因为它们已经提供了您正在寻找的内容。
另一方面,您可以通过使用观察者模式在缺乏事件的语言中编写事件驱动。
Yes, they are the mainly same.
Events are something like a "built-in" observer pattern template for some languages.
Thus, you wouldn't really implement the observer pattern in a language which supports events as they already provide what you are looking for.
On the other hand, you can write event-driven in languages which lack events by using the observer pattern.
观察者模式的一大优点是安全。当被观察者对象内发生代码更改时,所有观察者都必须实现新的更改。如果我们使用事件来代替,事件侦听器将不会对新事件的实现做出反应。换句话说,观察者规定事件必须由观察者处理。
在我的一个项目中,我遇到了一种情况,其中一个被观察者对象被破坏,需要在这样做之前通知观察者。我唯一要做的就是添加通知作为所有观察者的要求,并在观察者被摧毁之前触发事件。这里的美妙之处在于,只有所有观察者都为新创建的事件实现了处理程序,代码才会编译,因此您不太可能忘记更改其中的一些观察者。就我而言,我有相当数量的可能的观察者,很高兴知道我可以进行更改而不会产生一些或更多隐藏的错误。
这些品质使得观察者模式不像简单地抛出一个事件并让观察者自己决定那样灵活。但是,在使用事件时,请小心隐藏在拐角处的意大利面条怪物,并且只有在截止日期临近时才会出现。可能很多人都和我一样,不止一次遇到过这个丑陋的野兽。
换句话说,尽可能务实,并仍然使用正确的工具来完成工作。这意味着当您需要灵活性时使用事件,而当您需要控制时使用观察者。
One of the great things about the observer pattern is safety. When code changes occur within the observee object, all observants must implement the new changes. If we would have used events instead, the event listener would not react to the implementation of new events. In other words, the observee dictates that events must be handled by the observers.
In one of my projects I came across a situation where one of the observee objects became destroyed and observers needed to be notified, before doing so. The only thing that I had to do was add the notification as a requirment for all of the observers, and fire the event before the observee got destroyed. The beauty here is that the code only compiles if all observers implement a handler for the newly created event, therefore you will less likely forget to change a few of them. In my case I had a decent amount of possible observers, and it is nice to know that I can make changes without creating a few or more hidden bugs.
These qualities makes the observer pattern less flexible than simply throw an event, and let the observers decide for themselfs. But, when using events, beware for the great spaghetti monster that hides around the corner, and only comes out when deadlines are near. There's probably more than a few of you that have, just like me, come across this ugly beast more than once.
In other words, be as pragmatic as possible and still use the right tools for the job. This means using event when you need flexibility and the observer when you need control.
我已经搜索了一些同样的问题。
对于这个线程,我发现 Angel O'Sphere 关于“什么语义”的观点和 Spacerat 关于“调度程序”的观点确实有帮助。
这两点是我的理解,区分偶数驱动程序和观察者模式。至少从规范的解释来看,“观察者模式”通常表示一旦“主题”发生变化就立即广播,并且通过调用订阅者或监听者提供的接口来实现“调度”。而对于事件驱动,在“Subject”和“Observer”之间总是有另一层。要么称为“Dispatcher”,要么使用“Event Queue”。这提供了“延迟”处理以减少CPU使用率,并且还提供了调用不同的功能的能力。接口取决于不同的事件类型。
I've searched a bit for this same question.
For this thread, I find point from Angel O'Sphere on "What semantics" and point from Spacerat on "Dispatcher" do helps.
That two points are my understanding that distinguish Even-Driver from Observer Pattern. At least from canonical explanation, "Observer Pattern" usually represents an immediate broadcasting once the "Subject" has changed and the "Dispatching" is implemented by calling the interface provided by subscriber or listener. While for Event-Driven, there is always another layer between "Subject and "Observer". Either called "Dispatcher" or using "Event Queue". This provides the "delayed" handling to reduce CPU usage and also provides certain capability on calling different interfaces depends on different event type.
我尝试得很简单,因为这也对我有帮助。
只要作为观察者和可观察者来思考。与可观察量标记 setChanged 以及观察者向可观察量请求已更改的内容不同,可观察量改为向观察者广播一个对象(事件携带状态),其中包含有关更改的所有相关信息。所以观察者和被观察者之间实际上多了一个实例。
http://www.grahambrooks.com/event-driven -架构/模式/有状态事件模式/
I try it very simple, because that helped me once too.
Just think as a Observer and Observable. Instead that the observable marks a setChanged and the observer requests from the observable what has changed, the observable instead broadcasts an object (Event Carried State) with all relevant information about the change to the observers. So there is actually one more instance between the Observer and the Observable.
http://www.grahambrooks.com/event-driven-architecture/patterns/stateful-event-pattern/
两者的基本区别在于耦合和同步行为。如果我们坚持观察者模式,我们说只有一个信号源,并且它是同步的,而另一方面,对于事件,我们将双方解耦以独立工作,同时考虑拥有多个信号源的可能性未来的事件无需更改任何代码。事件帮助我们拥抱异步设计。所有反应式编程库都为事件驱动设计提供了很好的支持。
The basic difference in both is coupling and synchronous behaviour. If we stick with observer pattern, we say there is only one source of signal and it would be synchronous, while on other hand with events, we decouple both parties to work independently and the same time entertain the possibility of having more than one source of events in future without any code changes. Events help us to embrace async as design. All Reactive programming library provide very good support for event driven design.
事件驱动是一种软件范例或编写代码的风格,其中对象使用事件进行通信。某些语言(例如 C#)本身就支持事件。您可以让一个对象引发另一个对象侦听的事件。观察者模式是实现相同结果的另一种方法。
Event-driven is a software paradigm or style of writing code where objects communicate using events. Some languages like C# have native support for events. You can have an object raise an event to which another object listens to. The Observer Pattern is another way to achieve the same result.
来自维基百科:
观察者模式更加抽象和理论化。事件是一种(通常是内置的)实现,但是正如 Angel 的回答中所指出的,除了观察者模式中严格定义的情况之外,事件往往能够用于其他一些情况。
From Wikipedia :
The observer pattern is a little more abstract and theoretical. Events are one (commonly built-in) implementation, however as noted in Angel's answer Events tend to be able to be used in a few other situations apart from what is strictly defined in the observer pattern.