在工作中,我们有一个庞大的框架,并使用事件将数据从一部分发送到另一部分。我最近开始了一个个人项目,我经常想用事件来控制我的对象的交互。
例如,我有一个播放声音效果的混音器类,我最初认为我应该接收播放声音效果的事件。然后我决定只让我的类静态并调用
Mixer.playSfx(SoundEffect)
在我的课程中。我有很多像这样的例子,我最初想到的是事件的实现,然后改变主意,对自己说这太复杂了。
那我何时应该在项目中使用事件?在哪些情况下事件比其他技术有明显的优势?
答案 0 :(得分:11)
您通常使用事件来通知订阅者有关对象上发生的某些操作或状态更改的信息。通过使用事件,您可以让不同的订阅者做出不同的反应,并通过将订阅者(及其逻辑)与事件生成器分离,该对象变得可重用。
在你的混音器示例中,我有事件发出声音效果播放开始和结束的信号。如果我在桌面应用程序中使用它,我可以使用这些事件来启用/禁用UI中的控件。
答案 1 :(得分:4)
调用子例程和引发事件之间的区别与:规范,选举,基数以及最终,哪一方,发起者或接收者具有控制权。
通过呼叫,发起方选择来调用接收例程,发起方指定接收方。这导致了多对一的基数,因为许多呼叫者可能会选择调用相同的子例程。
另一方面,对于事件,启动器会引发一个事件,该事件将由选举接收该事件的例程接收。接收器指定它将从哪些启动器接收的事件。这导致一对多基数,因为一个事件源可以有许多接收器。
因此,关于呼叫或事件的决定主要与发起者是否确定接收者或接收者确定发起者有关。
答案 2 :(得分:3)
它在简单性和可重用性之间进行权衡。让我们来看一个“发送电子邮件”过程的比喻:
如果您知道收件人并且数量有限,您可以随时确定,就像将它们放入“收件人”列表并按下发送按钮一样简单。它很简单就像我们大多数时候使用的那样。这是直接调用函数。
但是,如果是邮件列表,您事先并不知道有多少用户要订阅您的电子邮件。在这种情况下,您创建一个邮件列表程序,用户可以在其中订阅,并且电子邮件会自动发送给所有订阅的用户。这是事件建模。
现在,即使在上述两个选项中,电子邮件都发送给用户,您可以更好地判断何时直接发送电子邮件以及何时使用邮件列表程序。应用相同的判断,希望你能得到答案:)
干杯,
阿吉特。
答案 3 :(得分:0)
我在之前的工作场所一直在使用庞大的代码库,并且已经看到,使用事件会大大增加复杂性,而且通常是不必要的。
为了修复或扩展现有代码,我经常不得不对现有代码进行逆向工程。 在这两种情况下,当您可以简单地阅读函数调用列表而不仅仅是查看事件的发生时,更容易理解发生了什么。
该事件迫使您寻找用法以完全了解正在发生的事情。现代 IDE 没有问题,但是如果您随后遇到许多也会引发事件的函数,它很快就会变得复杂。我遇到过这样的情况,即函数订阅事件的顺序很重要,即使大多数语言甚至不保证调用顺序...
在某些情况下,使用事件确实是个好主意。但在开始比赛之前,请考虑替代方案。它可能更易于阅读和维护。
使用事件的一个经典示例是 UI 框架,它提供按钮等元素。 您希望框架的函数“ButtonPressed()”调用您的一些函数,以便您可以对用户操作做出反应。 您可以订阅的事件的替代方案,例如是 UI 框架公开的公共 bool“buttonPressed” 并且您可以定期检查是否为真或假。当有数百个 UI 元素时,这当然是非常低效的。