The place where random ideas get written down and lost in time.
2017-03-21 - Event Bus
Category DEVCabThrottle uses the new Event Bus design I made up in 2014.
Pros and cons:
- Pro: The event bus implementation is simple and minimalist.
- Pro: There is no annotation processor to find subscribers, so no complicated build setup.
- Cons: It suffers from the typical good/bad part of a disconnected sub-system. The whole point is to remove hard dependencies, but the side effect is that it hides the dependencies. They are still there, just not so visible.
- Pro: The "user" dependencies are simple enough to find. Search for code using any of the bus constants to find the users. Done.
- Cons: The bus messages rely on a numeric ID and the simple naive approach used is to create "namespaces", a.k.a. ID ranges. E.g. 1000 is the base for the Discovery bus messages. But it doesn't say what is the max, and there's no centralized place to look at all the usage ranges (on purpose, because decentralized). That means it's hard to place it in a library and be sure there won't be conflicts down the road with something else.
- Cons: There's some inefficiency in sending messages to subscribers without knowing if they want to listen to them. The receivers can subscribe to message class types, but that's not too useful when for example sending a string notification.
So really the weakness is the ID range issue. Ideally each message would use an enum but the Java implementation of enums kind of sucks -- can't make a "generic" enum, and they are too heavy for serialized number sequences. Another alternative is to use a hash code as a base (e.g. NSD DiscoveryMixin.class.getHashCode() but even that is not guaranteed to not have collisions and it would prevent from making static final int IDs.
It does bring back some potential for dagger.
In usage, I mostly use the event bus for notification, obviously. E.g. NSD discovery mixing sends bus messages when a new host appears or vanishes. Well I can just register a listener and be done with it, since that's essentially what the event bus does. One point of the event bus is that the subscriber could be a view or something that does not have access to the sender object because it would require passing everything via globals or something, as I used to do before. Well that particular problem is well solved by dagger. E.g. there would be a module for the discovery client and whatever code need to use it, be it the activity to start the client or the UI to display its state, can simply access it via injection, then subscribe a listener as needed.
Same goes for throttles for example.
The other realization is that this seems to also fit the Reactive pattern of having observable streams. Each bus is essentially a stream, and users can get the stream via dagger.
Worth looking into it.