Implementation of pub sub pattern in Java
A few days back I came across a great article on PubSub (Publisher Subscriber) vs Observer pattern. While there are many code example on observer pattern I thought there is still some space for one more example for PubSub pattern in Java.
In this article, we will see an implementation of pub subpattern without confusing it with PubSub between servers which usually works via messaging queues or other high-level mechanisms. We are rather going to look into pub subpattern within one JVM
Summarizing the article written by Ahmed, the observer pattern requires the observer and subscriber to be aware of each other. For example; if there are two classes. TaxRates.java and InvoiceHandler.java, for InvoiceHandler, to “observe” TaxRates they have to know about each other’s existence. i.e. you may see the code in InvoiceHandler that looks like taxRates.observe(this);
On the other side, the PubSub pattern does not require mutual dependency. Rather they subscribe to events, any object in the system can send events to a broker and all the listeners will be able to react to that event via a single broker.
Just a few days back I saw a piece of code that looked like the following which seemed like a fitting place to apply PubSub pattern.
In the code above, the business case is, whenever tax rates change other classes should be made aware of it. In this particular example, all the dependent classes are singletons.
If you look at it from PubSub angle Invoice.java, QuotesAndProposols.java and IncomeTax.java should subscribe to any change that happens in TaxRates.
There are two issues with this code, if not more.
- As the number of classes depending on Publisher increases refresh method becomes more and more clunky with multiple if statements
- The publisher gets edited a lot as more dependent classes are added, this creates issues if you are using a large system and Publisher has to be distributed as a jar file.
To mitigate these issues we can implement a Broker which can be subscribed to like the following.
In the following gist, Broker.getInstance().register is being used to register the Invoice object as a subscriber to ON_TAX_CHANGE event.
Now whenever ON_TAX_CHANGE event occurs the update method of all the subscribers should be executed.
The code in TaxRates.java will change like the following.
Once sendMessage for ON_TAX_CHANGE is called update method of all the subscribers will be executed.
So in conclusion; here we saw an implementation of a PubSub pattern where our original class did not have to change whenever new observers are added to the system. Also, unlike the observer pattern here the Observer and Observable both were entirely disconnected.
I have created a code review for implementation of this, would love to get some suggestions there.