有什么“代码气味”征兆表示需要事件侦听器模型?


10

代码库中的哪些症状指示需要使用事件侦听器方法?

在我看来,当某些类需要被多个调用,而不是在其他类的设计时集合中定义时,您需要某种信令框架,但是我想听听还有哪些其他情况通过更改为基于事件的模型进行了改进。

Answers:


8

事件/侦听器方法试图避免紧密耦合,因此所有表明这一点的代码气味都将指向该方法。

基于此,我建议以下症状:

  • 大型构造函数,因为每个对象都需要知道其他每个对象,否则就无法运行。obj.set_dependecy(x)在构造函数调用之后,可能立即伪装了许多。

  • 双向依赖性,因为在没有事件的情况下,使用命令式语言,信息流基本上是“推送”(调用某人的方法)

  • “知识等级”很难确定。这是双向依赖关系,这是另一个焦点:如果有A,它听B,A知道B,但是B不知道A,所以有一个“层次”:有些对象什么都不知道,有些对象知道其他等等。例如,当像这样实现MVC时:http : //en.wikipedia.org/wiki/Model_View_Controller,模型只知道自身,视图知道模型,而控制器知道视图和模型。


1
到目前为止,双向依赖性是您需要切换到事件驱动模型的最明显的标志。构造函数膨胀可能意味着,但不仅仅是,不仅仅是意味着您需要以聚合,组合和/或常规抽象的方式(即重构,而不是设计更改)做更多的事情。
Aaronaught 2011年

你是对的。我试图通过易于检测对其进行排序,而大型构造函数是如此简单,以至于它们可能会被正则表达式捕获。
keppla 2011年

6

当您不知道或不知道应该对一组消息/信号/事件做出什么反应时。

通常,当您想让“世界”了解某个模块(一个类或一个类的系统)中发生的某些事情时,却又不想打扰被调用的事物。

具体而言,相关的代码味道是当您感觉开始混合来自独立模块的代码时,一个模块正在执行另一模块应该做出的反应。一旦看到必须根据模块A的状态/事件从模块B调用代码,就需要事件侦听器。


3

我会改变您的问题并说:何时基于事件不是面向对象应用程序的正确解决方案?我认为,如果将大多数面向对象的应用程序设计为事件生产者和消费者,则它们可以从中受益。

最后,“方法调用”实际上是一条消息到达某个对象,该对象负责确定是否要对该消息做某事并执行操作。这在强类型语言(例如Java)中不是很清楚,但是在动态语言(例如Ruby)中则更加明显。

将应用程序设计为基于事件的另一个有趣之处在于,通常必须将内部组件正确隔离和统一,否则代码会非常非常迅速地变得一团糟。举个例子,我真的很喜欢Alistair Cockburn所用的“ 六角形建筑”的概念,因为通常这种模式会产生更好的封装,并(我认为)会迫使更多的内聚部件。

我认为(但我可能错了),这也与域事件的域驱动设计概念有关,在域概念中,域类发出由其他对象捕获的事件,而这些对象又发出其他事件(您会看到哪里这是:D)。我喜欢这种模式的原因是,接口应该为角色建模,而不是实现。

抱歉,如果我没有太多道理,我在过去的几个月中一直在尝试这些模式,并获得了惊人的效果,但是我仍在尝试了解这些概念以及它们的作用范围。


2

考虑一下如果事件监听器(也称为观察者模式)不存在,您将要做什么。

如果您有一个引用了其他对象列表的对象,并在过程中的给定点调用了这些对象上的方法,则您肯定应该在那里有一个事件。

如果您在某个对象上有一个标志来表明已完成某项操作,并且正在查看其他对象上的该标志,则绝对应该使用事件驱动的模型。

但是,不要将其与回调混淆。如果您在另一个对象上调用一个方法,并在给定的时间将其传递给原始对象上的一个方法以进行回调,则应采用这种方式,而不是使用事件侦听器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.