【问题标题】:What is the advantage to using an event-driven approach vs procedural programming? [closed]使用事件驱动方法与过程编程相比有什么优势? [关闭]
【发布时间】:2015-10-23 10:33:06
【问题描述】:

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


没有 EDP:

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

使用 EDP:

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


使用其中一种是否有优势?我正处于需要选择的十字路口。但是,我没有任何客观信息来说明哪一个更胜一筹,以及在哪些方面一个比另一个更有优势。

谢谢!

编辑:我以与此处描述的方式类似的方式理解差异:https://stackoverflow.com/a/28135353/3547347

【问题讨论】:

  • 视情况而定。例如,当对象 D 被添加到系统中时,您需要做什么?这可能多久发生一次?您的设计应该由您的需求驱动。而且“游戏编程”有点过于宽泛,无法进一步评论。
  • 您的“事件驱动模型”和“非事件驱动模型”都是事件驱动模型。您只是使用了不同的术语来描述相同的行为。
  • 将相关信息打包到 EventArgs 等对象中并不是事件驱动方法所固有的。它只是一种设计模式,可以轻松实现前向兼容性(添加参数),而不会破坏公共 API。
  • 首先,GUI 处理事件(您不仅有“ObjectA”对用户输入做出反应;GUI 中的所有控件都对用户输入做出反应,而您不知道哪个是一个将由用户选择)。
  • 我大概只是​​对它有一个初步的了解。如果您有对象 A,然后根据某些输入调用对象 B、C、D....等中的方法。与对象 一个发布事件“ThingHappened”,而不是“知道”或“关心”哪些其他对象订阅了该事件。怎么一样?

标签: oop events architecture event-handling


【解决方案1】:

使用其中一个有优势吗?

是的 - 使用事件解耦 ABC。没有事件,例如,您不能通过让 另一个 类型响应 As 事件而不修改 As 代码来扩展功能。

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

【讨论】:

  • 感谢您的回复。所以如果我理解正确的话,将 A、B 和 C 解耦可以更容易地扩展功能,而无需修改 A 的代码。但是,它使程序更加复杂,因为您不能只看到您正在调用的方法,您只能看到有一个事件,但很难看到谁/什么订阅了该事件。不确定这是否是不好的做法,但是我可以通过一些文档来更轻松地进行逻辑跟踪吗?
【解决方案2】:

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

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

所以我想说,考虑到这两个选项,请始终使用事件驱动模型。

【讨论】:

  • 让一个类型订阅一个事件然后调用两个不同的方法,而不是让这两个方法分别订阅事件,这不仅仍然使用事件驱动模型,而且在许多情况下都非常合适实例(当然,不是所有实例)。
【解决方案3】:

我认为您在谈论观察者模式。

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

【讨论】:

    【解决方案4】:

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

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

    这种方法的优点是更抽象(以稍微复杂一点为代价)。所以你可以做一些事情,比如在“观察者”和“响应者”之间放置一个队列,这可以让你控制和观察你的过程,并扩展你的系统。

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

    【讨论】:

    • 感谢您的回复。也许使用用户输入是一个不好的例子?我知道 IO 几乎总是事件处理。我说的是之后程序如何响应。可以说我点击一个“单位”。点击、它的位置以及它点击的任何对象都被打包和发布。然后你有一个响应这个的方法,并根据位置或对象命中它调用其他对象中的方法,然后执行相同的操作......等等而不是在其他方法中调用对象,我会在链中使用它和其他方法只需发布和订阅事件。
    • 如果我理解正确,同样的原则也适用。如果您想控制级联事件,请在“观察者”和“响应者”之间放置一个队列。实际上,您是在让孩子们耐心地排队等候。队列可以是内存中的数据结构,也可以是它自己的进程,例如零 mq,或者是建立在关系数据库上的自旋作业队列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 2018-06-09
    相关资源
    最近更新 更多