200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > [js高手之路]设计模式系列课程-发布者 订阅者重构购物车

[js高手之路]设计模式系列课程-发布者 订阅者重构购物车

时间:2022-12-30 23:33:14

相关推荐

[js高手之路]设计模式系列课程-发布者 订阅者重构购物车

发布者订阅者模式,是一种很常见的模式,比如:

一、买卖房子

生活中的买房,卖房,中介就构成了一个发布订阅者模式,买房的人,一般需要的是房源,价格,使用面积等信息,他充当了订阅者的角色

中介拿到卖主的房源信息,根据手头上掌握的客户联系信息(买房的人的手机号),通知买房的人,他充当了发布者的角色

卖主想卖掉自己的房子,就需要告诉中介,把信息交给中介发布

二,网站订阅信息的用户

订阅者角色:需要订阅某类信息的网民,如某个网站的javascript类型文章

发布者角色:邮箱服务器,根据网站收集到的用户订阅邮箱,通知用户.

网站主想把信息告诉订阅者,需要把文章相关内容告诉邮箱服务器去发送

等等非常多的例子,不一一列举

本文用网站订阅的方式,推导发布者-订阅者框架,然后用发布者-订阅者框架来重构一个简单的购物车

varSite={};Site.userList=[];Site.subscribe=function(fn){this.userList.push(fn);}Site.publish=function(){for(vari=0,len=this.userList.length;i<len;i++){this.userList[i].apply(this,arguments);}}Site.subscribe(function(type){console.log("网站发布了"+type+"内容");});Site.subscribe(function(type){console.log("网站发布了"+type+"内容");});Site.publish('javascript');Site.publish('html5');

Site.userList就是用来保存订阅者

Site.subscribe就是具体的订阅者,把每一个订阅者订阅的具体信息保存在Site.userList

Site.publish就是发布者:根据保存的userList,一个个遍历(通知),执行里面的业务逻辑

但是这个,发布订阅者模式,有个问题,不能订阅想要的类型,上例我加了2个订阅者(第11行,第14行),只要网站发了信息,全部能收到,但是有些用户可能只想收到javascript或者html5的,所以,接下来,我们需要继续完善,希望能够接收到具体的信息,不是某人订阅的类型,就不接收

varSite={};Site.userList={};Site.subscribe=function(key,fn){if(!this.userList[key]){this.userList[key]=[];}this.userList[key].push(fn);}Site.publish=function(){varkey=Array.prototype.shift.apply(arguments),fns=this.userList[key];if(!fns||fns.length===0){console.log('没有人订阅'+key+"这个分类的文章");returnfalse;}for(vari=0,len=fns.length;i<len;i++){fns[i].apply(this,arguments);}}Site.subscribe("javascript",function(title){console.log(title);});Site.subscribe("es6",function(title){console.log(title);});Site.publish("javascript","[js高手之路]寄生组合式继承的优势");Site.publish("es6","[js高手之路]es6系列教程-var,let,const详解");Site.publish("html5","html5新的语义化标签");

输出结果:

[js高手之路]寄生组合式继承的优势

[js高手之路]es6系列教程 - var, let, const详解

没有人订阅html5这个分类的文章

我们可以看到,只有订阅了javascript类型文章的人,才能收到 ”寄生组合式继承的优势” 这篇文章,发布html5类型的时候,没有任何人会收到.

es6类型的,只有订阅es6的人,才能收到

我们已经有了一个基本的发布订阅者框架,接下来,把他完善成一个框架,便于其他功能或者其他网站系统的相同功能可以重用他

varEvent={userList:{},subscribe:function(key,fn){if(!this.userList[key]){this.userList[key]=[];}this.userList[key].push(fn);},publish:function(){varkey=Array.prototype.shift.apply(arguments),fns=this.userList[key];if(!fns||fns.length===0){console.log('没有人订阅'+key+"这个分类的文章");returnfalse;}for(vari=0,len=fns.length;i<len;i++){fns[i].apply(this,arguments);}}};varextend=function(dstObj,srcObj){for(varkeyinsrcObj){dstObj[key]=srcObj[key];}}varSite={};extend(Site,Event);Site.subscribe("javascript",function(title){console.log(title);});Site.subscribe("es6",function(title){console.log(title);});Site.publish("javascript","寄生组合式继承的优势");Site.publish("es6","es6系列教程-var,let,const详解");Site.publish("html5","html5新的语义化标签");

然后,我们来重构一个购物车实例,没有重构之前,我的购物车用的是面向过程:

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><scriptsrc="js/cart.js"></script></head><body><divid="box"><ul><li><inputtype="button"value="-"><spanclass="num">0</span><inputtype="button"value="+"><span>单价:</span><spanclass="unit">15元;</span><spanclass="label">小计:</span><spanclass="subtotal">0</span>元</li><li><inputtype="button"value="-"><spanclass="num">0</span><inputtype="button"value="+"><span>单价:</span><spanclass="unit">10元;</span><spanclass="label">小计:</span><spanclass="subtotal">0</span>元</li><li><inputtype="button"value="-"><spanclass="num">0</span><inputtype="button"value="+"><span>单价:</span><spanclass="unit">5元;</span><spanclass="label">小计:</span><spanclass="subtotal">0</span>元</li><li><inputtype="button"value="-"><spanclass="num">0</span><inputtype="button"value="+"><span>单价:</span><spanclass="unit">2元;</span><spanclass="label">小计:</span><spanclass="subtotal">0</span>元</li><li><inputtype="button"value="-"><spanclass="num">0</span><inputtype="button"value="+"><span>单价:</span><spanclass="unit">1元;</span><spanclass="label">小计:</span><spanclass="subtotal">0</span>元</li></ul><divclass="total-box">商品一共<spanid="goods-num">0</span>件;一共花费<spanid="total-price">0</span>元;其中最贵的商品单价是<spanid="unit-price">0</span>元</div></div></body></html>

cart.js文件:

functiongetByClass(cName,obj){varo=null;if(arguments.length==2){o=obj;}else{o=document;}varallNode=o.getElementsByTagName("*");varaNode=[];for(vari=0;i<allNode.length;i++){if(allNode[i].className==cName){aNode.push(allNode[i]);}}returnaNode;}functiongetSubTotal(unitPrice,goodsNum){returnunitPrice*goodsNum;}functiongetSum(){//计算总花费varaSubtotal=getByClass("subtotal");varres=0;for(vari=0;i<aSubtotal.length;i++){res+=parseInt(aSubtotal[i].innerHTML);}returnres;}functioncompareUnit(){//比单价,找出最高的单价varaNum=getByClass("num");varaUnit=getByClass("unit");vartemp=0;for(vari=0;i<aNum.length;i++){if(parseInt(aNum[i].innerHTML)!=0){if(temp<parseInt(aUnit[i].innerHTML)){temp=parseInt(aUnit[i].innerHTML);}}}returntemp;}window.onload=function(){varaInput=document.getElementsByTagName("input");vartotal=0;varoGoodsNum=document.getElementById("goods-num");varoTotalPrice=document.getElementById("total-price");varoUnitPrice=document.getElementById("unit-price");for(vari=0;i<aInput.length;i++){if(i%2!=0){//加号aInput[i].onclick=function(){//当前加号所在行的数量varaNum=getByClass("num",this.parentNode);varn=parseInt(aNum[0].innerHTML);n++;aNum[0].innerHTML=n;//获取单价varaUnit=getByClass("unit",this.parentNode);varunitPrice=parseInt(aUnit[0].innerHTML);varsubtotal=getSubTotal(unitPrice,n);varaSubtotal=getByClass("subtotal",this.parentNode);aSubtotal[0].innerHTML=subtotal;total++;//商品总数oGoodsNum.innerHTML=total;oTotalPrice.innerHTML=getSum();oUnitPrice.innerHTML=compareUnit();}}else{aInput[i].onclick=function(){varaNum=getByClass("num",this.parentNode);if(parseInt(aNum[0].innerHTML)!=0){varn=parseInt(aNum[0].innerHTML);n--;aNum[0].innerHTML=n;//获取单价varaUnit=getByClass("unit",this.parentNode);varunitPrice=parseInt(aUnit[0].innerHTML);varsubtotal=getSubTotal(unitPrice,n);varaSubtotal=getByClass("subtotal",this.parentNode);aSubtotal[0].innerHTML=subtotal;total--;//商品总数oGoodsNum.innerHTML=total;oTotalPrice.innerHTML=getSum();oUnitPrice.innerHTML=compareUnit();}}}}}

耦合度太高,可维护性很差.

重构之后的购物车:

window.onload=function(){varEvent={userList:{},subscribe:function(key,fn){if(!this.userList[key]){this.userList[key]=[];}this.userList[key].push(fn);},publish:function(){varkey=Array.prototype.shift.apply(arguments),fns=this.userList[key];if(!fns||fns.length===0){returnfalse;}for(vari=0,len=fns.length;i<len;i++){fns[i].apply(this,arguments);}}};(function(){varaBtnMinus=document.querySelectorAll("#boxli>input:first-child"),aBtnPlus=document.querySelectorAll("#boxli>input:nth-of-type(2)"),curNum=0,curUnitPrice=0;for(vari=0,len=aBtnMinus.length;i<len;i++){aBtnMinus[i].index=aBtnPlus[i].index=i;aBtnMinus[i].onclick=function(){(this.parentNode.children[1].innerHTML>0)&&Event.publish("total-goods-num-minus");--this.parentNode.children[1].innerHTML<0&&(this.parentNode.children[1].innerHTML=0);curUnitPrice=this.parentNode.children[4].innerHTML;Event.publish("minus-num"+this.index,parseInt(curUnitPrice),parseInt(this.parentNode.children[1].innerHTML));};aBtnPlus[i].onclick=function(){(this.parentNode.children[1].innerHTML>=0)&&Event.publish("total-goods-num-plus");this.parentNode.children[1].innerHTML++;curUnitPrice=this.parentNode.children[4].innerHTML;Event.publish("plus-num"+this.index,parseInt(curUnitPrice),parseInt(this.parentNode.children[1].innerHTML));}}})();(function(){varaSubtotal=document.querySelectorAll("#box.subtotal"),oGoodsNum=document.querySelector("#goods-num"),oTotalPrice=document.querySelector("#total-price");Event.subscribe('total-goods-num-plus',function(){++oGoodsNum.innerHTML;});Event.subscribe('total-goods-num-minus',function(){--oGoodsNum.innerHTML;});for(leti=0,len=aSubtotal.length;i<len;i++){Event.subscribe('minus-num'+i,function(unitPrice,num){aSubtotal[i].innerHTML=unitPrice*num;});Event.subscribe('plus-num'+i,function(unitPrice,num){aSubtotal[i].innerHTML=unitPrice*num;});}})();console.log(Event.userList);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。