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();
3 commenti:
After read this:
http://www.javaworld.com/javaworld/javaqa/2001-05/04-qa-0525-observer.html
I understand that is not a Correct implementation of Observer / Subject.
In fact in this design pattern the Subject Raise the Event, not the Observer, so I was totally wrong.
after read http://www.dustindiaz.com/javascript-publisher/
I update Observer, now you can chain , and I found a bug,solved thanks to constructor!!
here the example in the link, modified to use my 'class':
Observer.prototype.subscribe =function(who){who.registerObserver(this);return this;}
var NewYorkTimes = new Subject();
var AustinHerald = new Subject();
var SfChronicle = new Subject();
function _update(name,from){
alert('Delivery from '+from+' to '+name);
}
var Ken=new Observer;
var ChunLi=new Observer;
var Ryu=new Observer;
Ken.update=function(e){
_update("Ken",e);
}
ChunLi.update=function(e){
_update("ChunLi",e);
}
Ryu.update=function(e){
_update("Ryu",e);
}
Ken.subscribe(NewYorkTimes);
ChunLi.subscribe(AustinHerald).subscribe(SfChronicle).subscribe(NewYorkTimes);
Ryu.subscribe(AustinHerald).subscribe(SfChronicle);
NewYorkTimes.notifyObserver("NewYork Times");
SfChronicle.notifyObserver("Street Fighters Chronicle");
AustinHerald.notifyObserver("Austin Herald");
just followed your link from dean's base.js page. I tried your example and it helped understand even further.
Thanks.
Posta un commento