Informal talks with colleagues around the coffee machine are a great way to improve your developer skills. Most of the time, people don’t agree and that’s a good way to learn about thinking in context. One of the latest subject was about the Event Bus. Though no Android developer, I’m part of a Mobile team that uses an Event Bus to dispatch events among the different components of the application. Amazingly enough (at least for me), one team member doesn’t like Event Bus. As coincidence go, I just happened to read this post a few days later.
I guess it’s my cue to make a case for Event Bus.
There are several abstractions available to implement messaging, one of the first that comes to mind probably being the Observer pattern. It’s implemented in a variety of UI frameworks, such as AWT, Swing, Vaadin, you name it. Though it reverses the caller responsibility from the Subscriber (aka Observer) to the Observable (aka Subject), this pattern has a big drawback: in order for Subscriber to be notified of Observable’s event firing, the Observable has to hold a reference to a collection of Subscribers. This directly translates as strong coupling between them, though not in the usual sense of the term.
To decrease coupling, the usual solution is to insert a third-party component between the two. You know where I’m headed: this component is the Event Bus. Now, instead of Observers registering to the Subject, they register to the Event Bus and Subject publishes events to the Event Bus.
The coupling between Subject and Observer is now replaced by a coupling between Subject and EventBus : the Observable doesn’t need to implement a
register() method with the Subscriber’s type as a parameter. Thus, the event can come from any source and that source can change in time with no refactoring needed on the Subscriber’s part.
In the Java world, I know of 3 different libraries implementing Event Bus:
- Green Robot (aimed at Android)
- Otto (also aimed at Android) by Square (updated thanks to @dpolyshuk)
- Vaadin Spring Boot’s Event Bus
In the latest two, the implementation of the
notify() method is replaced by the use of annotation while in the former, it’s based on an agreed upon method signature(i.e.
onEvent(Event)). Thus, any type can be notified, removing the need to implement an
Observer interface so that the coupling is reduced even further.
Finally, all those implementations offer a way to pass an additional payload in the form of an event. This is the final design:
Advantages of this design are manifold:
- No need to reference both the Subscriber and the Observable in a code fragment to make the later register the former
- No need to implement an
- Ability to pass additional payload
- Many-to-many relations: one Subscriber can subscribe to different events, and an Observable can send different kind of events
The only con, but it might be an issue depending on your context, is the order in which events are published. In this case, a traditional coupled method-calling approach is better suited. In all other cases – especially in the user interface layer and even more so when it’s designed with true graphical components (AWT, Swing, Android, Vaadin, etc.), you should give Event Bus a shot given all its benefits.
For example, here’s an old but still relevant article on integrating Guava Event Bus with Vaadin.