Working with GoF's Design Patterns in JavaScript Programming
page 5 of 8
by Xianzhong Zhu
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 80086/ 155

Working with the Observer Pattern

As above, let us first look at the definition of the Observer pattern.

(1) Concept

The Observer pattern defines a relationship between objects so that when one changes its state, all the others are notified accordingly. Generally, you are suggested to consider leveraging the Observer pattern under the following conditions.

·         When an abstract model contains two parts, one depending on the other, you need to seal these twos independently in order to change and reuse them respectively and independently.

·         When you want to change an object then in the meantime you have to change other objects, but do not know how many objects need the related change.

·         When an object has to notify other objects, but it cannot suppose who the other objects are. In other words, you do not hope that these objects are closely coupled.

(2) Example

Underneath, we are going to apply the Observer pattern to a simple yet typical JavaScript event handling mechanism. First, we need to do some preparation, namely expanding the Array object with two methods (i.e. indexOf and removeAt below), as shown in Listing 12.

Listing 12 - Expand the Array object

//expand the properties of the destination object
//, copy all the properties of the source object 
//, to the destination
Object.extend=function(destination,source){
for(property in source){
destination[property]=source[property];
}
return destination;
}
// expand the built-in Array object
Object.extend(Array.prototype,{
//retrieve the object in the array
indexOf: function (object){
for(var i=0,1ength=this.length; i<length; i++)
     if(this[i]==object) return i;
return -1;
},
//remove the specified element in the array
removeAt: function (index){
if(index<0 || index>=this.length) return null;
switch(index){
case 0:
return this.shift();
break;
case this.length -1:
return this.pop();
break;
default:
var head=this.s1ice(0,index);
var tail=this.s1ice(index+1);
var ele=this[index];
this=head.concat(tail);
return ele;
break;
}
}
});

Next, define two classes, i.e. Observer and Subject. The code related to the Observer class is shown below:

//the Observer class
function Observer(){}
object.extend(Observer.prototype, {
//note that the later instantiation Observer
  will override this Update method
Update:function(){
return;
}
});

The code related to the Subject class is as follows.

Listing 13

// the Subject class
function Subject(){}
Object.extend(Subject.prototype,{
//an array of the Observer objects
observers:[],
// notify per Observer object to execute the Update method
notify:function(context){
for(var i=0; i<this.observers.length; i++)
this.observers[i].Update(context);
},
//add a new Observer
addObserver:function(observer)  {
if(!observer.Update)
throw new Error(“addObserver error!”);
this.observers.push(observer);
},
//delete the existing Observer
removeObserver:function(Observer)  {
if(!observer.Update)
throw new Error(“removeObserver error!”);
this.observers.removeAt(this.observers.indexOf(observer));
},
});

OK, for now we have defined all the objects relating to the Observer pattern. The following lists the steps to carry out the Observer pattern:

·         Establish an instantiation of the Subject class.

·         Establish several instantiations of the Observer object, overriding their Update methods respectively.

·         Subscribe all the Observer objects to the Subject object.

·         Send out a notice through the Subject object, when the Observers objects are subscribed to the Subject object will execute their Update methods respectively.

·         If you need to cancel a certain Observer object's subscription for the Subject object, you can invoke the removeObserver method.

Finally, we are to set up an example to show you the application of the Observer pattern, as well as the objects defined above. First, Establish a Subject object and define a publishEvent method for it.

Listing 14

//Create a new Subject object
var concreteSubject=new Subject();
// define a new publishEvent method with which to 
 notify all the Observer of the related data
concreteSubject.publishEvent=function(data){
document.write(“published:”+data);
this.notify(data);
}

Then, establish two Observer objects; overlay their Update methods respectively.

Listing 15

// create a new Subject object
var concreteSubject=new Subject();
// define a new publishEvent method with which to 
 notify all the Observer of the related data
concreteSubject.publishEvent=function(data)  (
document.write(“published:”+data);
this.notify(data);
}
 
// Create a new Observer object and override its
 Update method
var concreteObserverl=new Observer();
concreteObserverl.Update=function(data){
document.write(“concreteObserverl 
 received:”+data);
}
 
//subscribe concreteObserverl to concreteSubject
concreteSubject.addObserver(concreteObserverl);
 
// create the second Observer object and override
  its Update method
var concreteObserver2=new Observer();
concreteObserver2.Update=function(data){
document.write(“concreteObserver2 
 received:”+data);
}
 
//subscribe concreteObserver2 to concreteSubject
concreteSubject.addObserver(concreteObserver2);

Now, let us carry out the publishEvent method of the concreteSubject object, sending out a notice.

Listing 16

concreteSubject.publishEvent(“msg”);

At this time, the application will output the following.

Listing 17

published:msg
concreteObserverl received:msg
concreteObserver2 receired:msg

Such results proved that concreteObserverl and concreteObserver both received a notice from the concreteSubject object. Next, you can use the removeObserver method to cancel a subscription for the concreteSubject object.

Listing 18

concreteSubject.removeObserver(concreteObserver2);

Again send out a notice:

Listing 19

concreteSubject.publishEvent(“msg”);

This time, only concreteObserver receives the notice and the application will output the following.

Listing 20

published:msg
concreteObserver1 receired:msg

Using the Observer pattern can implement the typical event mechanism in the JavaScript environment. Those who are acquainted with the Ajax development may know of the two famous client-side Ajax frameworks--Prototype and Dojo. In fact, the two frameworks both adopt the similar means herein to introduce their respective event mechanisms. Readers who have interests with this can study further.


View Entire Article

User Comments

No comments posted yet.

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-28 4:17:36 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search