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&&indexSubject拥有增加和删除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程序设计有所帮助。