Oop 与过程编程相比,使用事件驱动方法的优势是什么?

Oop 与过程编程相比,使用事件驱动方法的优势是什么?,oop,events,architecture,event-handling,Oop,Events,Architecture,Event Handling,使用事件驱动方法与非事件驱动(程序)方法的优缺点是什么 无EDP时: 对象A响应某些用户输入。对象A调用对象B中的方法和对象C中的方法,它们执行各自的任务 使用EDP: 对象A响应某些用户输入。对象A发布订阅了对象B和C的事件。相关数据打包到EventArgs中,由B&C接收并执行各自的任务 使用一个或另一个有好处吗?我正处在一个需要选择的十字路口。然而,我没有任何客观的信息表明哪一方优于另一方,以及在哪些方面一方可能优于另一方 谢谢 编辑:我以一种类似于这里描述的方式来理解这种差异:可扩展

使用事件驱动方法与非事件驱动(程序)方法的优缺点是什么


无EDP时:

对象A响应某些用户输入。对象A调用对象B中的方法和对象C中的方法,它们执行各自的任务

使用EDP:

对象A响应某些用户输入。对象A发布订阅了对象B和C的事件。相关数据打包到EventArgs中,由B&C接收并执行各自的任务


使用一个或另一个有好处吗?我正处在一个需要选择的十字路口。然而,我没有任何客观的信息表明哪一方优于另一方,以及在哪些方面一方可能优于另一方

谢谢


编辑:我以一种类似于这里描述的方式来理解这种差异:

可扩展性和维护。不必每次在不带EDP的示例中添加新的“订户”时都返回到方法并添加到它,您只需将要调用的方法添加到订户列表中即可

OOP就是要封装代码中发生更改的部分,以便更改它们的后果尽可能少。您不希望每次需要项目中其他地方的新功能时都必须修改一个模糊相关的类

所以我想说,如果有这两种选择,请始终使用事件驱动模型

使用一个或另一个有好处吗

是-使用事件可以解耦
A
B
C
。例如,如果没有事件,则无法通过让另一种类型响应
A
s事件而不修改
A
s代码来扩展功能


缺点是,编写代码比较困难(虽然不是很困难),您必须编写更多的“管道”来添加所有相关事件。这也使得跟踪逻辑变得更加困难,因为您不知道在任何时候都可能在监听
A
s事件。

我想您所说的是观察者模式


在实现对象A时,如果没有对象B和对象C,则使用观察者模式;或者,如果您以后知道了这一点,那么其他类将需要了解事件,但您不希望它们必须修改对象A的代码。

事件驱动编程是处理IO绑定进程的并发模型(如示例中的用户输入)。所以,实际上,您描述的两个过程都是事件驱动的

这两个示例之间的区别在于,通过在“观察者”对象和“响应者”对象之间引入发布/订阅抽象,正如D Stanley所提到的,通过添加一层间接寻址来解耦这两个层

这种方法的优点是更大的抽象性(以稍微复杂一点为代价)。因此,您可以在“观察者”和“响应者”之间设置一个队列,这样您就可以控制和观察您的流程,并扩展您的系统


例如,您的“观察者”可以是一个前端应用程序,它将作业排队到队列服务器,队列服务器由“响应者”查询,响应者是在其他服务器上运行的其他应用程序。这将是构建多层应用程序的一种方法。

这取决于具体情况。例如,当对象D添加到系统中时,您必须做什么?这种情况多久会发生一次?您的设计应该由您的需求驱动。“游戏编程”有点过于宽泛,无法进一步评论。您的“事件驱动模型”和“非事件驱动模型”都是事件驱动模型。您只是使用了不同的术语来描述相同的行为。将相关信息打包到诸如
EventArgs
之类的对象中并不是事件驱动方法所固有的。它只是一种设计模式,可以在不破坏公共API的情况下轻松实现前向兼容性(添加参数)。首先,GUI处理事件(不仅“ObjectA”对用户输入作出反应;GUI中的所有控件都对用户输入作出反应,您不知道用户将选择哪个控件).我可能只是对它有一个初步的了解。如果你有一个对象A,它根据一些输入调用对象B,C,D…中的方法。与对象相比,发布事件“ThingOccessed”,而不“知道”或“关心”订阅该事件的其他对象。这是怎么回事?让一个类型订阅一个事件,然后调用两个不同的方法,而不是让这两个方法分别订阅事件,这不仅仍然使用事件驱动模型,而且在许多情况下(当然,不是所有情况下)都非常合适。谢谢您的回复。也许使用用户输入是一个糟糕的例子?我知道IO几乎总是由事件处理的。我说的是节目在那之后的反应。假设我点击一个“单位”。单击、它的位置以及它命中的任何对象都将打包并发布。然后你会有一个方法响应它,并根据命中的位置或对象调用其他对象中的方法,然后调用其他对象中的方法,然后执行相同的操作…等等,而不是在其他方法中调用对象,我会让它和链下的其他方法只发布和订阅事件。如果我理解正确,同样的原则也适用。如果您想要控制事件的级联,那么在“观察者”和“响应者”之间放置一个队列。实际上,你让孩子们耐心地排队等候。队列可以是内存中的数据结构,也可以是它自己的进程(如zero mq),或者是构建在关系数据库上的自纺作业队列。感谢您的回复。因此,如果我理解正确的话,解耦A、B和C可以更容易地扩展功能,而无需修改A的代码。然而,这使得p