资讯专栏INFORMATION COLUMN

javascript之代理模式

MAX_zuo / 341人阅读

支持原作者,购买地址链接描述

概念

代理模式
代理模式(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

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

缓存代理

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

//demo
var 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) 过去的。

实际中

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

将请求合并缓存做处理。

重构之后 会补充文章。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91113.html

相关文章

  • Javascript设计模式——代理模式

    摘要:最近在读设计模式与开发实践,在这里把文中的各种设计模式写出来,以便加深记忆,也可以分享给初学者。经纪人可以全权代表明星和客户谈判,最后把谈判结果给明星,明星决定签约与否。这也违反了面向对象设计原则中的单一职责原则。 最近在读《javascript设计模式与开发实践》,在这里把文中的各种设计模式写出来,以便加深记忆,也可以分享给初学者。如果你不了解设计模式,那么强烈推荐你阅读一下这本书,...

    cuieney 评论0 收藏0
  • 100行代码让您学会JavaScript原生的Proxy设计模式

    摘要:面向对象设计里的设计模式之代理模式,相信很多朋友已经很熟悉了。代表当前执行方法的实例,即方法调用者。代表具体的方法名称。现在我们再次调用,传入构造器返回的代理对象打印输出,代理逻辑生效了和的一样优雅地实现了代理设计模式。 showImg(https://segmentfault.com/img/remote/1460000016760603);面向对象设计里的设计模式之Proxy(代理...

    txgcwm 评论0 收藏0
  • javascript设计模式学习笔记代理模式

    摘要:代理模式代理模式是为一个对象提供一个代用品或者占位符以便控制对它的访问引入代理模式,其实是为了实现单一职责的面向对象设计原则。 代理模式 代理模式是为一个对象提供一个代用品或者占位符, 以便控制对它的访问 引入代理模式,其实是为了实现单一职责的面向对象设计原则。 虚拟代理 将一些开销很大的对象, 延迟到正真需要的时候执行 // 针对大图 增加loading图 ...

    big_cat 评论0 收藏0
  • 细谈JavaScript中的一些设计模式

    摘要:注意事项声明函数时候处理业务逻辑区分和单例的区别,配合单例实现初始化构造函数大写字母开头推荐注意的成本。简单工厂模式使用一个类通常为单体来生成实例。 @(书籍阅读)[JavaScript, 设计模式] 常见设计模式 一直对设计模式不太懂,花了一下午加一晚上的时间,好好的看了看各种设计模式,并总结了一下。 设计模式简介 设计模式概念解读 设计模式的发展与在JavaScript中的应用 ...

    30e8336b8229 评论0 收藏0
  • JavaScript设计模式结构型设计模式

    摘要:享元模式通过分析应用程序的对象,将其解析为内在数据和外在数据,减少对象数量,从而提高程序的性能。通过这种方式进行事件绑定,可以减少事件处理程序的数量,这种方式叫做事件委托,也是运用了享元模式的原理。事件处理程序是公用的内在部分,每个菜单项各 github 全文地址 : YOU-SHOULD-KNOW-JS JavaScript设计模式之外观模式 概念 外观模式:为一组复杂子系统接口提...

    xiaoqibTn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<