Buses are not dead !
Buses appeared on Android some years ago with Otto, forked from an intern component of Guava, one of the Google core libraries. After Otto, arrived EventBus, a more complete solution permitting, among others, inheritance in subscriber classes, delivery threads and priority on receiving.
Recently Otto has been deprecated in favor of RxAndroid, a more advanced library, making also possible a communication by event. Buses stay simple ways to answer to a certain kind of problems met on Android.
Buses permit the application of the Publisher/Subscriber model (PubSub).
In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers, but instead characterize published messages into classes without knowledge of which subscribers, if any, there may be. Similarly, subscribers express interest in one or more classes and only receive messages that are of interest, without knowledge of which publishers, if any, there are.
Subscribe / unsubscribe to the Bus :
When to use a bus ?
When a certain number of problems occur :
- communications between entities not directly linked (propagation of a message through different layers, eg : listener of listener)
- many listeners
- 1-X communications
When not to use a bus ?
- long chain of events (prefer RxAndroid)
- inter-process communication (use bounded services)
- less boilerplate code
- lower coupling -> better maintenability
- 1-X communications easier to setup
- asynchronous task : error management, guaranteed delivery
- easier to test (mock of message vs mock of activity)
- less structuring (no interface implementation to link the components)
- potentially confusing : be careful with readers which resend messages
- additional abstraction
- do not use for all communications (eg : not for direct communications)
- avoid the resend of message from a subscriber method (even forbid it)
I will now detail the analysis by presenting the advantages of the use of a bus against the different native ways of communication.
Comparison with the native ways of communication
vs Communication by interface :
(eg : listener of Fragment)
- pros : less boilerplate code : interfaces (declarations and implementation), listener management (declaration, assignment and reattachment after recreate), direct communication between different layers
- cons : less structuring, creation of message objects
vs Communication by Intent :
(eg : LocalBroadcastManager, passing of Intent through multiple layers, asynctask callback following an orientation change)
- pros : type safe (vs extras), no serialization (vs parcelable), simpler API than LocalBroadcastManager
vs Communication by Handler/Message from a background thread :
(ex. : threads, services, etc.)
- pros : simpler, error management with AsyncExecutor (EventBus)
vs Observer Model :
(eg : Observer and ContentObserver)
- pros : simpler, less structuring code (declarations)
- cons : change of vision (message vs state changes)
The support of the historical Otto is stopped for RxAndroid, do we then have to migrate our buses to Rx ? In my opinion No.
Rx is more than a bus solution and brings a new paradigm (oriented toward functional programming), so more complex to setup. It is also more centered on the management of sequences of producer/consumer task.
Buses, especially, the more complete and optimized EventBus, have still its place on Android for simpler problems.
First published on jacquesgiraudel.com