martedì, ottobre 10, 2006

Observer Subscriber in Base

I was playing with Dean Edwards Base and I would to implement
the Observer Subscriver pattern.
I wrote this Observer implementation:


//Clone method
Base.prototype.clone=function(){return new Base(this);}

//Define the Observer class
var Observer= Base.extend({
subscribe:function (obj,evt){
//if(!this["on"+evt])this["on"+evt]=[];
if(typeof(this["on"+evt]) === "undefined")this["on"+evt]=[];
this["on"+evt].push(obj);
},
raise:function (evt){
var list=this["on"+evt];

if(list){
var max=list.length;
for(var i=0;i<max;i++)
//if(list[i].update)list[i].update();
if(typeof(list[i].update)!=="undefined")list[i].update();
}
}
});
//Define the subscriber class
var Subscriber = Base.extend({update:function(){alert("update() must be implemented");}});


and this little test

/*Simple example of implementation*/

//Istantantiate a Observer
var observer= new Observer();

//Define a Event
observer.evt=function(){
//do stuff
this.raise("evt");
}

//Istantiate a Subscriber
var subscriber1=new Subscriber();
//Clone a Subscriber
var subscriber2=subscriber1.clone();

//define a custom update function
subscriber2.update=function(){
alert("here update() was implemented");
}

//subscribe our 2 object
observer.subscribe(subscriber1,"evt");
observer.subscribe(subscriber2,"evt");

//Raise the event
observer.evt();


Base is Great, it was so simple!




Update!
As I said in the comment this wasn't a correct implementation.

A correct(I hope) is the follow implementation:

//Clone method
Base.prototype.clone=function(){return new Base(this);}

var Observer = Base.extend({
update:function(evt){
alert("update() must be defined");
}
});
var Subject = Base.extend({
observers:[],
constructor:function(){this.observers=new Array();},
registerObserver:function(obj){
this.observers.push(obj);
return obj;
},
unregisterObserver:function(obj){
if(this.observers.length>0)
var tmp=this.observers.pop();
if (tmp!==obj){
var max=this.observers.length;
for(var i=0;i<max;i++)
if(this.observers[i]===obj){this.observers[i]=tmp;break;}
}
return this;
},
notifyObserver:function(evt){
var max=this.observers.length;
for(var i=0;i<max;i++)
this.observers[i].update(evt);
}
});

And so the Test:

/*Example:*/
var subject = new Subject();
subject.x=0;
subject.add=function(){
this.x++;
this.notifyObserver();
}
var observer1 = new Observer();
var observer2 =observer1.clone();
observer1.update=function(){alert("now x is "+subject.x);}
observer2.update=function(){alert("something happened on subject")}

subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.add();
subject.unregisterObserver(observer2);
subject.add();
Posta un commento