JavaScript编程设计模式之观察者模式(Observer Pattern)实例详解
本文实例讲述了JavaScript编程设计模式之观察者模式。分享给大家供大家参考,具体如下:
简介
简单的解释观察者模式,就是一个对象(subject)维护一个依赖他的对象(observers)列表,当自身状态发生变化时,自动通知所有观察者对象。当某个对象不需要获得通知时,可以从对象列表中删除掉。
从上面的解释中我们可以提炼出三个componet:Subject,ObserverList和Observer,用JS实现很简单:
functionObserverList(){
this.observerList=[];
}
ObserverList.prototype.Add=function(obj){
returnthis.observerList.push(obj);
};
ObserverList.prototype.Empty=function(){
this.observerList=[];
};
ObserverList.prototype.Count=function(){
returnthis.observerList.length;
};
ObserverList.prototype.Get=function(index){
if(index>-1&&index
Subject拥有增加和删除Observer的能力
functionSubject(){
this.observers=newObserverList();
}
Subject.prototype.AddObserver=function(observer){
this.observers.Add(observer);
};
Subject.prototype.RemoveObserver=function(observer){
this.observers.RemoveAt(this.observers.IndexOf(observer,0));
};
Subject.prototype.Notify=function(context){
varobserverCount=this.observers.Count();
for(vari=0;i
最后定义一个观察者对象,实现update方法
//TheObserver
functionObserver(){
this.Update=function(){
//...
};
}
当有多个观察者,只需扩展上面的基本对象,并重写Update方法。
尽管观察则模式被广泛使用,但在JS中经常使用它的变体:发布订阅模式
发布订阅模式通过一个topic/event通道,解耦了观察者模式中Subject(发布者)和Observer(订阅者)之间耦合的问题,在JS中被广泛使用。
下面简单的例子说明了使用发布订阅模式的基本结构
//Averysimplenewmailhandler
//Acountofthenumberofmessagesreceived
varmailCounter=0;
//Initializesubscribersthatwilllistenoutforatopic
//withthename"inbox/newMessage".
//Renderapreviewofnewmessages
varsubscriber1=subscribe("inbox/newMessage",function(topic,data){
//Logthetopicfordebuggingpurposes
console.log("Anewmessagewasreceived:",topic);
//Usethedatathatwaspassedfromoursubject
//todisplayamessagepreviewtotheuser
$(".messageSender").html(data.sender);
$(".messagePreview").html(data.body);
});
//Here'sanothersubscriberusingthesamedatatoperform
//adifferenttask.
//Updatethecounterdisplayingthenumberofnew
//messagesreceivedviathepublisher
varsubscriber2=subscribe("inbox/newMessage",function(topic,data){
$('.newMessageCounter').html(mailCounter++);
});
publish("inbox/newMessage",[{
sender:"hello@google.com",
body:"Heythere!Howareyoudoingtoday?"
}]);
//Wecouldthenatalaterpointunsubscribeoursubscribers
//fromreceivinganynewtopicnotificationsasfollows:
//unsubscribe(subscriber1,);
//unsubscribe(subscriber2);
发布订阅模式的实现
许多Js库都很好的实现了发布订阅模式,例如Jquery的自定义事件功能。
//Publish
//jQuery:$(obj).trigger("channel",[arg1,arg2,arg3]);
$(el).trigger("/login",[{username:"test",userData:"test"}]);
//Dojo:dojo.publish("channel",[arg1,arg2,arg3]);
dojo.publish("/login",[{username:"test",userData:"test"}]);
//YUI:el.publish("channel",[arg1,arg2,arg3]);
el.publish("/login",{username:"test",userData:"test"});
//Subscribe
//jQuery:$(obj).on("channel",[data],fn);
$(el).on("/login",function(event){...});
//Dojo:dojo.subscribe("channel",fn);
varhandle=dojo.subscribe("/login",function(data){..});
//YUI:el.on("channel",handler);
el.on("/login",function(data){...});
//Unsubscribe
//jQuery:$(obj).off("channel");
$(el).off("/login");
//Dojo:dojo.unsubscribe(handle);
dojo.unsubscribe(handle);
//YUI:el.detach("channel");
el.detach("/login");
简单实现
varpubsub={};
(function(q){
vartopics={},
subUid=-1;
//Publishorbroadcasteventsofinterest
//withaspecifictopicnameandarguments
//suchasthedatatopassalong
q.publish=function(topic,args){
if(!topics[topic]){
returnfalse;
}
varsubscribers=topics[topic],
len=subscribers?subscribers.length:0;
while(len--){
subscribers[len].func(topic,args);
}
returnthis;
};
//Subscribetoeventsofinterest
//withaspecifictopicnameanda
//callbackfunction,tobeexecuted
//whenthetopic/eventisobserved
q.subscribe=function(topic,func){
if(!topics[topic]){
topics[topic]=[];
}
vartoken=(++subUid).toString();
topics[topic].push({
token:token,
func:func
});
returntoken;
};
//Unsubscribefromaspecific
//topic,basedonatokenizedreference
//tothesubscription
q.unsubscribe=function(token){
for(varmintopics){
if(topics[m]){
for(vari=0,j=topics[m].length;i
使用方法
//Anothersimplemessagehandler
//Asimplemessageloggerthatlogsanytopicsanddatareceivedthroughour
//subscriber
varmessageLogger=function(topics,data){
console.log("Logging:"+topics+":"+data);
};
//Subscriberslistenfortopicstheyhavesubscribedtoand
//invokeacallbackfunction(e.gmessageLogger)onceanew
//notificationisbroadcastonthattopic
varsubscription=pubsub.subscribe("inbox/newMessage",messageLogger);
//Publishersareinchargeofpublishingtopicsornotificationsof
//interesttotheapplication.e.g:
pubsub.publish("inbox/newMessage","helloworld!");
//or
pubsub.publish("inbox/newMessage",["test","a","b","c"]);
//or
pubsub.publish("inbox/newMessage",{
sender:"hello@google.com",
body:"Heyagain!"
});
//Wecabalsounsubscribeifwenolongerwishforoursubscribers
//tobenotified
//pubsub.unsubscribe(subscription);
//Onceunsubscribed,thisforexamplewon'tresultinour
//messageLoggerbeingexecutedasthesubscriberis
//nolongerlistening
pubsub.publish("inbox/newMessage","Hello!areyoustillthere?");
更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。