博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript之代理模式
阅读量:5896 次
发布时间:2019-06-19

本文共 3659 字,大约阅读时间需要 12 分钟。

支持原作者,购买地址

概念

  • 代理模式

    代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。
    在现实生活中,可以找到很多代理模式使用的场景。明星都有经纪人作为代理。如果请明星来演出,就要先同他的经纪人沟通,谈好相应的细节与报酬。再交给明星。
    需求:公司(Company)通过经纪人(agent)找明星(start)开演唱会

//演唱会var Concert = function(){}//公司var Company = {    askforconcert: function(target){       var concert = new Concert();       target.openconcert(concert )    }}//明星var star = {    openconcert: function(concert){         console.log("明星同意开一场演唱会")    }}//经纪人代理var agent = {    openconcert: function(concert){        star.openconcert(concert)    }}//执行Company.askforconcert(agent);  //=>明星同意开一场演唱会

这样 company直接把请求发给agent,agent再转给star,这样就完成了一个简单的代理模式

(compan=>agent=>star)


保护代理和虚拟代理

经济人可以帮助 明星过滤掉一些请求,比如 钱不够多或者场地不够好,这种请求可以直接在经纪人出被过滤拒绝掉。这种代理就叫做保护代理。 由经纪人Agent来控制对明星star的访问。- 如果A 通过 B 送花给C,我们可以在A的时候new 一个 flower传递给代理B,再由B决定什么时候或者是否要再转交个最终的target C。new Flower这个操作可以交给B,B决定可以送花给C的时候再由B做 new Flower的操作。这种模式就叫做虚拟代理。虚拟代理把一些开销很大的对象,延迟到真正需要它的时候才去创建
var Flower = function(){    this.price = 150}var a = {  sendflower: function(target){        var flower = new Flower()        target.receiveFlower(flower )    }}var b = {    receiveFlower: function(flower){        if(flower.price < 100){          console.log("太便宜了,女神表示一脸嫌弃")          return false        }else{            c.receiveFlower(flower)        }    },            }var c = {    receiveFlower: function(){        console.log("接受了鲜花")    }}

实现图片预加载

不是用代理设计模式的实现

var  preLoadImage = (function(){    var imgNode = document.createElement('img');    document.body.append(imgNode)    var img = new Image();    img.onload = function(){      imgNode.src = img.src    }    return {        setSrc: function(src){            imgNode.src = "loading.gif";            img.src = src;        }    }})()

使用代理模式的实现方式

var image = (function(){    var imgNode = document.createElement('img');    document.body.append(imgNode);    return {        setSrc: function(src){            imgNode.src = src;        }    }})()//代理var proxyImage = (function(){    var img = new Image();    img.onload = function(){        image.setSrc = img.src;    }    return {        setSrc: function(src){            image.setSrc = "loading.gif";            img.src = src;        }    }})
  • 单一职责原则

    单一职责指的是,对一个类而言,应该仅有一个引起他变化的原因。如果一个对象承担了多个原则,就意味着这个对象将变得巨大,引起他变化的原因可能也会有多个。面向对象设计鼓励将行为分不到细粒度的对象之中,如果一个对象承担的职责过多,等于把这些值得耦合到了一起,这种耦合会导致脆弱和低内聚的设计。当变化发生时,设计可能会遭到意外的破坏。(书中93页)

preLoadImage方法,承担了添加img标签,还有预加载两个功能,代码耦合到了一起,当我修改添加标签时,可能会影响到另一部分功能。

而用代理方法重构后,image方法只负责创建标签,设置src,预加载功能交给了proxyImage,解除了耦合的代码,两个功能互不干扰。

虚拟代理合并http请求

(page95)

var syncFile = function(id){    $.ajax({        data: {            id: id        }    })...}//绑定事件for(var i = 0;i

这里有个很严重的问题,每点一个都会发送一个ajax请求,性能上,这是一个很大的开销

  • 需求: 文件同步穿,选中的文件会被上传到服务器上,解决方法,我们可以 通过一个代理函数,来收集一段时间内的请求,将请求的参数缓存起来,与后端人员协商将选中的id作为一个数组传到后台保存。

var syncFile = function(ids){    $.ajax({        data: {            id: ids        }    })...}var proxyFile = (function(){    var cache = [],        timer = null;    return function(id){        cache.push(id);        if(timer){            return        }        timer = setTimeout(function(){            syncFile(cache.join(","))            clearTimeout(timer);            timer = null;            cache = [];        },2000)    }})()//绑定事件for(var i = 0;i

这样,有选中操作的话,不会频繁触发请求。

缓存代理

  • 缓存代理可以作为一些开销大的运算结果提供暂时的存储,下次运算时,如果传递进来的参数跟之前一致,则可以直接返回前面存储的运算结果

//demovar mult = function(){    console.log('开始计算结果')    var a  = 1;    for(var i = 0;i

return cache[args] = mult.apply(this,arguments),这里遇见个认知上的问题,一直在想,这里的this指针是指向window对象的,而mult函数,也在window对象下。思路卡住,没想明白为什么要用apply指一下指针,想了一下,原来是为了把这个参数apply进去。。。我真他妈的智障。参数是不能从 把代理里的arguments直接mult(arguments) 过去的。

实际中

积分商城项目的购物车之前由于赶工,请求处理的很粗糙,可以使用代理模式重新重构代码。

将请求合并缓存做处理。

重构之后 会补充文章。

转载地址:http://dvasx.baihongyu.com/

你可能感兴趣的文章
nagios短信报警(飞信fetion20080522004-linrh4)
查看>>
【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!...
查看>>
linux 将大文件分成小文件
查看>>
CCNA- 距离矢量路由协议学习
查看>>
企业实践用户邮箱导入/导出(第2部分)
查看>>
我的友情链接
查看>>
如何学习Linux命令-初级篇
查看>>
从Oracle Public Yum为Oracle Linux建立本地的Yum源
查看>>
在 SELECT 查询中使用表表达式
查看>>
静态路由和默认路由
查看>>
谈一谈Spring-Mybatis在多数据源配置上的坑
查看>>
【精益生产】车间现场管理的八大浪费
查看>>
关于阿里开发者招聘节 |这5道笔试真题 你会吗!???
查看>>
C#的异常处理机制
查看>>
vsftp:500 OOPS: could not bind listening IPv4 sock
查看>>
Linux安装BTCPayServer并设置比特币BTC和Lightning支付网关
查看>>
Python 的 with 语句
查看>>
mysql安装,远程连接,以及修改密码
查看>>
Mybatis查询返回Map类型数据
查看>>
java的深拷贝与浅拷贝
查看>>