Design Patterns: PubSub Explained


I actually wanted to write about PubSub alone: it’s a fascinating design pattern to me however, the thought occurred to me, why not write a design patterns’ series? It’ll be good knowledge for me and give good information. So here goes the first: PubSub.

Introduction

The pattern works using a middleman; an agent that bridges publishers and subscribers. Publishers are the objects that fire events when they are done doing some processing and subscribers are objects who wish to be notified when the publisher is done – i.e. they are interested in the work of publishers.

A good example is that of a radio station where people tune in to their favourite programs. The publisher has no knowledge of the subscribers or what programs they are listening to; he only needs to publish his program. Subscribers too have no way of knowing what goes on during program production; when their favourite program is running, they can respond by tuning in or informing a friend.

PubSub achieves very loose coupling: instead of looking for ways to link up two discrete systems; you can have one hand off messages and have the second part consume these messages.

Advantages

1. Loose coupling

Publishers do not need to know about the number of subscribers, what topics a subscriber is listening to or how subscribers work; they can work independently and this allows you to develop both separately without worrying about ripple effects, state or implementation.

2. Scalability

PubSub allows  systems to scale however it buckles under load.

3. Cleaner Design

To make the best use of PubSub, you have to think deeply about how the various components will interact and this usually leads to a clean design because of the emphasis on decoupling and looseness.

4. Flexibility

You don’t need to worry about how the various parts will fit; just make sure they agree to the one contract or the other i.e. publisher or subscriber.

5. Easy Testing

You can easily figure out if a publisher or subscriber is getting the wrong messages.

Disadvantages

PubSub’s greatest strength – decoupling – is also its biggest disadvantage.

  1. The middleman might not notify the system of message delivery status; so there is no way to know of failed or successful deliveries. Tighter coupling is needed to guarantee this.
  2. Publishers have no knowledge of the status of the subscriber and vice versa. How can you be sure everything is alright on the other end? You never can say…
  3. As the number of subscribers and publishers increase, the increasing number of messages being exchanged leads to instabilities in this architecture; it buckles under load.
  4. Intruders (malicious publishers) can invade the system and breach it; this can lead to bad messages being published and subscribers having access to messages that they shouldn’t normally receive.
  5. Update relationships between subscribers and publishers can be a thorny issue – afterall they don’t know about each other.
  6. The need for a middleman/broker, message specification and participant rules adds some more complexity to the system.

Conclusion

There are no silver bullets but this is one excellent way of designing loosely coupled systems. The same concepts drive RSS, Atom and PubSubHubbub.

PubSub Example (JavaScript)

var makePubSub = function () {
var callbacks = {},
publish = function (){
//Turn arguments object into real array
var args = Array.prototype.slice.call(arguments, 0);
//Extract the event name which is the first entry
var ev = args.shift();
//Return if callbacks object doesn't contain
//any entry for event
var list, i, l;
if(!callbacks[ev]) { return this; }
list = callbacks[ev];
//Invoke the callbacks, passing in the rest of parameters
for (i=0, l=list.length; i<l; i=i+1){
list[i].apply(this, args);
}
return this;
},
subscribe = function (ev, callback){
//Check if ev is already registered
// If it isn't create an array entry for it
if(!callbacks[ev]){
callbacks[ev] = [];
}
callbacks[ev].push(callback);
return this;
};
return {pub: publish, sub: subscribe};
};
test = makePubSub()
test.sub('alert', function(){alert('hello');})
test.pub('alert')
view raw gistfile1.js hosted with ❤ by GitHub

20 thoughts on “Design Patterns: PubSub Explained

  1. return {pub: publish, sub: subscribe};

    Benefits of dynamic language. I wonder how many interfaces and class it will take to write the same in my beloved Java.

    Like

  2. This dude is fantastic! One of these days I should reach your level..but the question is when I’m at your level, will it be your current level or your level then? *smile*

    Like

    1. it’s an object because he needs Map-like access to the specific alert by name (so instead of callbacks[0], he wants callbacks[‘alert’], which will bring back a list of events to pop-off and process).

      Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.