Eventbus是中介者模式还是观察者模式?

17

Eventbus更像中介者还是观察者?据Google数据,"eventbus mediator"有2,430个搜索结果,而"eventbus observer"则有3,850个搜索结果。

从描述来看,它们都符合我所尝试的内容(中介者甚至更符合)。 那么,Eventbus是否实现了特定的模式,或者由我来决定它是哪种模式?

5个回答

19

通常情况下,一个特定的代码片段并不固有地属于某种设计模式或另一种。这就是为什么它们被称为“模式”(而不是“实现技术”)的原因。许多软件看起来有点像一种模式,但也类似于另一种--这是好事。最好不要为了模式而遵循模式,而是将它们用作讨论架构的共享词汇。

EventBus是这样的工具。我编写它时考虑到了类似Observer的情况,但如果你适当地构建你的应用程序,它可以扮演中介者的角色。


12
EventBus 的通常用法是触发事件。使用“Observer”这个词更加贴切。观察者模式使用事件或消息来通知感兴趣的对象有关所观察的对象(发生变化)的信息。
中介者也试图将两个实现解耦,但在某种意义上比观察者更具体,它可以了解两个对象/接口的全部内容,并作为粘合剂使它们工作。观察者不声称了解内部甚至接口的情况。它只知道或关心的是当事件发生时,它需要通知感兴趣的对象。
中介者可能是一种特定的场景设置,而观察者可能更加通用。
由于 EventBus 几乎总是在应用程序范围内作为单例存在,我肯定会将 EventBus 归类为使用 Observer,因为在大多数情况下,其真正的目的是在运行时在各个模块/对象之间全局地促进消息传递。

7

我会说,一个典型的事件总线利用了这两种模式:

  • 事件总线基本上封装了其他对象之间的通信方式,因此它是中介者
  • 注册为事件处理程序/监听器的对象是观察者(而他们所观察的主体是事件类型和/或产生这些事件的对象,不是总线本身),因此就像 wikipedia says 观察者模式 "主要用于实现分布式事件处理系统"(强调我的),但是事件总线本身并不是观察者。

4
刚刚偶然看到这个,想要点赞并发表一条评论来补充答案 - 实际上,回到 Go4 书中,他们在实现部分中提到,Mediator 模式中的 Mediator 对象可以被实现为一个 Observer。因此,设计模式有一种混合的方式。像往常一样,区别在于目的/意图:Mediator 用于将交互逻辑视为“独立关注点”,只需为 Colleague 对象定义某种类型的通信接口即可。Observer 的目的是支持发布-订阅交互(事件)。 - Filip Milovanović

5

维基百科:中介者模式的本质是“定义一个封装了一组对象如何交互的对象”

EventBus并不完全符合这个模式。

EventBus也不是观察者模式,因为如果你有N个对象并且想要在它们之间进行通信,使用观察者模式需要N*N个观察者,而只需一个全局EventBus即可完成同样的工作。

因此,EventBus是THE EventBus模式。


不确定我是否完全理解需要N˟N个观察者的那一行。如果N个对象都需要彼此通信,则每个对象都是发布者和订阅者。因此,您有N个订阅者(观察者),每个订阅者都有N个订阅。订阅仅是一种方法调用,用于将一个对象注册到另一个对象;它不会创建新的观察者,因此观察者的总数仍为N。如果生产者需要一次订阅一个订阅,则可能需要N˟N个方法调用;但在现代应用程序中,所有这些初始连接可能都由DI容器执行。 - jaco0646
3
事件总线不是一种设计模式,而是三种设计模式的混合:单例模式、观察者模式和中介者模式。它是单例模式,因为你只需要一个总线实例。 它是观察者模式,因为你有发布者-订阅者。 它是中介者模式,因为你有一个封装了一组对象如何交互的对象(总线)。因此,事件总线不是一种模式,而是三种模式的具体实现。 - Jorge Rivera
这应该是正确的答案。 - Arialdo Martini

0

由于前言中提到了“一个...发布/订阅API”,我会选择Observer。


看起来还不错,但我也注意到观察者和中介者是非常相似的模式。 - Stefan
1
是的,它们是不同的。观察者模式中,主题知道观察者列表并进行管理。然而,维基百科[http://en.wikipedia.org/wiki/Observer_pattern]认为发布/订阅本身就是一种模式,所以我想这个问题是有争议的。 - Simone

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