“事件驱动”和“面向对象”编程有什么关系?

14
现在,我几乎在各个地方听到“事件驱动”编程的说法。
维基百科称:
在计算机编程中,“事件驱动编程”是一种编程范式,程序的流程由用户操作(鼠标点击、按键等)、传感器输出或来自其他程序/线程的消息等事件决定。事件驱动编程是图形用户界面和其他应用程序(如JavaScript Web应用程序)中使用的主要范式,这些应用程序的重点是响应用户输入执行某些操作。
这难道不就是我们的老朋友OOP吗?如果这不是OOP,那它和OOP有什么区别呢?

你认为这段文字中哪些内容是“完全符合”面向对象编程(OOP)的? - Andy Ray
4个回答

19
  1. 面向对象编程(OOP)和事件驱动编程(EDP)是正交的,这意味着它们可以一起使用。

  2. 在OOP结合EDP时,所有OOP原则(封装、继承和多态性)保持不变。

  3. 在OOP结合EDP时,对象获得了一些发布事件通知并订阅其他对象事件通知机制。

  4. OOP带/不带EDP之间的区别在于对象之间的控制流程。

    • 在没有EDP的OOP中,控制从一个对象移动到另一个对象的方法调用。对象主要调用其他对象的方法。

    • 在带有EDP的OOP中,控制从一个对象移动到另一个对象的事件通知上。对象订阅来自其他对象的通知,然后等待所订阅的对象发出通知,根据通知执行某些操作并发布自己的通知。

  5. 结论:OOP+EDP是“我们老朋友OOP”,通过事件驱动设计使控制流程反转。


你的短语“控制流反转”很棒。不过,要以那种方式看待事物有点困难...这就是我对如今教授编程的疑惑所在。必须轻松地处理基本的、根本性的、截然不同的范式。当然,可以倒立骑自行车。简单吧。 - user4624979

7
面向对象编程将数据和行为配对,形成一个真实世界对象的模型。事件驱动编程是一种编程风格,在这种编程方式下,我们有一个服务器等待输入命令,无论是在通信端口还是用户界面上。然后它将处理该命令并显示/生成所需的结果。
大多数事件驱动语言都是面向对象的。对象等待事件发生。面向对象语言中的程序不一定是事件驱动的,而事件驱动编程也不一定需要面向对象的语言。它们是无关的。

从你的回答中,我并不清楚它们之间的区别。我们可以将每个事件视为真实的实体,也可以在面向对象编程中采用客户端-服务器设计。这有什么新意?到底有什么变化?这些都已经存在了。 - Mohsen Kamrani
2
区别在于编程范式。我可以用COBOL编写事件驱动程序。假设我编写了一个服务器,它监听请求并发送响应。COBOL不是面向对象的,但我可以在其中编写事件驱动程序。面向对象语言的概念是能够创建一个构造,例如Java类,它封装了组成对象的数据和对象执行的操作。对象不一定必须响应事件。事件驱动编程是一种程序类型,而面向对象则更像是一种语言类型。 - Brian English
从您的例子中我得出的结论是:事件驱动编程是面向对象编程的超集。显然,OO程序中的所有对象并不都会响应事件,但在每个重要的应用程序中,每个对象直接或间接地(作为辅助对象)都会响应事件。 - Mohsen Kamrani
把面向对象的语言看作是一组工具,可以让你构建程序。不同的语言和不同的范例(如面向对象的语言)存在是为了提供不同的工具集来解决问题。事件驱动程序似乎很突出,因为这些是你与之交互最多的程序。在工作中,我们处理银行的批处理周期程序。这些是处理大量数据文件的大型程序。虽然有一些事件驱动触发器,例如报告生成,但它只是一个数据处理器,不会响应外部事件。 - Brian English
事件驱动程序解决事件驱动问题。最好将程序与需要解决的问题相匹配,而不是反过来。 - Brian English

6
一个顺序(非事件驱动)程序的算法就像一份食谱:从头开始,一直工作到结束,然后停止。而一个事件驱动的程序更像是汽车的控制器:任何事情都可能在任何时间以任何顺序发生。
面向对象的原则似乎更适用于事件驱动模型,因为每个“控件”基本上与其他控件无关(关注点分离),事件顺序大多不重要,时间巧合也不重要:您可以同时开启雨刷器、关闭除霜器、转向和加速,这些操作并不会相互影响。在某些情况下,食谱也可能具备这种特性,但需要由厨师(编译器/优化器/ CPU)来推断。
顺序程序也可以是面向对象的:如果搅拌机和烤箱是独立的且各自完成其任务,那么也无妨。希望这个类比有用。

1
真的很喜欢这个比喻(y) - Harry

2

我来试一下。这里有三个隐喻:

事件编程似乎类似于硬件总线的工作方式:总线用于外围设备之间进行通信。同样,一个手机塔是手机之间通信的信息总线。还考虑一下古老的星型网络拓扑模型(https://en.wikipedia.org/wiki/Star_network)。看看家庭路由器如何将计算机和物联网设备连接到家庭网络。

我们不是使用外围设备、手机或设备,而是编写对象。我们不是沿着传输协议发送数据包,而是向消息代理(例如消息队列或Kafka)发送事件或消息。事件可供感兴趣的任何人处理,或者在工作流程的情况下,预计某个人会处理该事件,并且发送方将期望找到一个具有与结果相应的响应的结果事件。

旁注:经验教训

因此,我们可能也有关于硬件制造商和电信工程师已经遇到并解决的有关事件驱动消息的问题的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接