EventBus 框架的简易实现
Google Guava 是 Google 公司内部 Java 开发工具库的开源版本,它提供了一些新功能或对 JDK 已有功能的增强功能。其中就包括:集合(Collections)、缓存(Caching)、原生类型支持(Primitives Support)、并发库(Concurrency Libraries)、通用注解(Common Annotation)、字符串处理(Strings Processing)、数学计算(Math)、I/O、事件总线(EventBus)等等。
在 站内文章观察者模式:订阅与推送 文章中,我们介绍了观察者模式的同步阻塞的实现方式和异步非阻塞实现方式。本文将介绍使用 Google Guava EventBus 让观察者模式的实现过程更加灵活和简易,并亲自动手写一个简易版的 EventBus。
从观察者模式开始
使用 Google Guava EventBus 的观察者模式代码:
1 | public interface Subject { |
利用 EventBus 框架实现的观察者模式,跟经典的同步阻塞观察者模式的代码相比,实现思路大致一样,都需要定义 Observer
,并且通过 registerObserver()
函数注册 Observer
,也都需要通过调用某个函数(比如,EventBus 中的 post()
函数)来给 Observer
发送消息(在 EventBus 中消息被称作事件 event
)。
但在实现细节方面,它们又有些区别。基于 EventBus,我们不需要定义 Observer
接口,任意类型的对象都可以注册到 EventBus 中,通过 @Subscribe
注解来标明类中哪个函数可以接收被观察者发送的消息。
Guava EventBus 的结构与功能
Guava EventBus 对外暴露的所有可调用接口,都封装在 EventBus
类中。其中,EventBus
实现了同步阻塞的观察者模式,AsyncEventBus
继承自 EventBus
,提供了异步非阻塞的观察者模式。
1 | EventBus eventBus = new EventBus(); // 同步阻塞模式 |
EventBus 类提供了 register()
函数用来注册观察者。它可以接受任何类型(Object
)的观察者。而在经典的观察者模式的实现中,register()
函数必须接受实现了同一 Observer
接口的类对象。post()
函数,用来给观察者发送消息。
1 | public void register(Object object); |
跟经典的观察者模式的不同之处在于,当我们调用 post()
函数发送消息的时候,并非把消息发送给所有的观察者,而是发送给可匹配的观察者。所谓可匹配指的是,能接收的消息类型是发送消息(post
函数定义中的 event
)类型的父类。
1 | // AObserver能接收的消息类型是XMsg,BObserver能接收的消息类型是YMsg,CObserver能接收的消息类型是ZMsg。 |
EventBus 通过 @Subscribe
注解来标明,某个函数能接收哪种类型的消息。比如在下面的代码中,当通过 register()
函数将 DObserver
类对象注册到 EventBus 的时候,EventBus 会根据 @Subscribe
注解找到 f1()
和 f2()
,并且将两个函数能接收的消息类型记录下来(PMsg
->f1
,QMsg
->f2
)。当我们通过 post()
函数发送消息(比如 QMsg
消息)的时候,EventBus 会通过之前的记录调用相应的函数 f2()
。
1 | public DObserver { |
项目地址
示例项目:uuanqin/Simple-EvenBus: EvenBus 框架的简单实现