Coding Guru

Code never does the mistake, we make the mistakes in the code. Think, Imagine, Phrase and then Code.

The Observer Pattern

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

This is one of the most famous design pattern for JavaScript applications. It offers a model with subscription feature where the objects are being subscribed with an event and whenever an event occurs the subscribed object is notified. This is the cutting edge technology when working with the event driven programming. Its a loosely coupled design and provides a better object oriented approach.

In an application many event handlers are created which are triggered on an event. These handlers receive the event arguments with all the details of the triggered event like onClick, onLoad etc. In simpler words observer pattern is also known as publication/subscription or pub/sub model. Normally we add the event handlers by using addEventListener or jQuery methods: on, delegate, live, click, etc…

In the language of engineers the observer pattern facilitates a Subject to publish the changes to one or more Observers. The subject hold the reference of all the observers and by using this reference it notifies the observer.

Diagram


Participants

The participants for this pattern are:

  • Subject - In sample code: Click
    • Holds the observer reference. Can have multiple observers for the same update
    • Facilitates the observer to subscribe or unsubscribe at any point of time
    • Notifies the observers whenever any update is made
  • Observers - In sample code: clickHandler
    • Hols a signature method which is called when a subject is updated


Wanna Try The Code

The mySubject is the subject and the myHandlers is the observer. The following code shows how to subscribe, unsubscribe and re-subscribe when the event is triggered. The observer receives notification from eventOne and eventThree only.

Notice that trigger method takes two arguments. first one is the event details and second about the context. If no context is passed then it defaults to the window.

    function mySubject() {
this.myHandlers = []; // observers
}

mySubject .prototype = {

subscribe: function(fn) {
this.myHandlers.push(fn);
},

unsubscribe: function(fn) {
this.myHandlers = this.myHandlers.filter(
function(item) {
if (item !== fn) {
return item;
}
}
);
},

fire: function(o, thisObj) {
var scope = thisObj || window;
this.myHandlers.forEach(function(item) {
item.call(scope, o);
});
}
}

// log helper

var log = (function() {
var log = "";

return {
add: function(msg) { log += msg + "\n"; },
show: function() { alert(log); log = ""; }
}
})();

function run() {

var clickHandler = function(item) {
log.add("fired: " + item);
};

var subj = new mySubject();

subj.subscribe(clickHandler);
subj.fire('eventOne');
subj.unsubscribe(clickHandler);
subj.fire('eventTwo');
subj.subscribe(clickHandler);
subj.fire('eventThree');

log.show();
}

Advantages

  • Helps to manage dependencies
  • Requires a deeper bonding of relationship between the various modules/components of the application
  • Its a decoupled approach which promotes the smaller and reusable components

Disadvantages

  • Checking the integrity of your application can become difficult
  • Switching a subscriber from one publisher to another can be costly

When to Use

  • When the actions or state of an object depends on actions or state of another object.

  • When a change in an object has to update multiple dependent objects.

  • When one object has to notify other objects about the update without any knowledge about these other objects.


Pingbacks and trackbacks (1)+

Loading