美文网首页程序员
JS设计模式之代理模式

JS设计模式之代理模式

作者: Splendid飞羽 | 来源:发表于2020-07-26 22:06 被阅读0次

定义:

为其他对象提供一种代理以控制对这个对象的访问。
何时使用:想在访问一个类时做一些控制。

如何解决:增加中间层。

应用实例:
1、明星使用经纪人做代理,请明星演出,只能联系他的经纪人,经纪人将所有演出细节和报酬谈妥之后,再将合同给明星签字。
2、买火车票不一定在火车站买,也可以去代售点。
如下图所示,就是在中间增加一个中间层做代理,例如es6的Proxy就是一个很好地例子

image.png

使用场景:
按职责来划分,通常有以下使用场景:
1、远程代理。
2、虚拟代理。
3、Copy-on-Write 代理。
4、保护(Protect or Access)代理。
5、缓存代理。
6、防火墙(Firewall)代理。
7、同步化(Synchronization)代理。
8、智能引用(Smart Reference)代理。

本文主要讲述的是js中常用的两种代理模式------> 虚拟代理和缓存代理

1、我们先来看如何使用虚拟代理实现图片的懒加载
//创建img对象,设置setSrc方法
let myImg = {
    setSrc(imgNode, src){
        imgNode.src = src;
    }
}
//创建代理对象,处理真正的逻辑
let ProxyImg = {
    setSrc(imgNode, src){
        myImg.setSrc(imgNode, 'file://image/loading.gif');
        let img = new Image();
        img.onload = () => {
            myImg.setSrc(imgNode, src);
        }
        img.src =  src;
    }
}

let imgNode = document.createElement('img');
imgSrc = 'https://upload.jianshu.io/users/upload_avatars/1413261/a0f9887a-
24f8-408c-bfd1-2975924e8f02.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/80/h/80/format/webp'
document.body.appendChild(imgNode);
ProxyImg.setSrc(imgNode, imgSrc);

上面的代码比较粗糙的解释了代理模式的作用,下面进行代码的优化

let myImg = (() =>{
    let imgNode = document.createElement('img');
    document.body.prepend(imgNode);
    return {
        setSrc(src){
            imgNode.src = src;
        }
    }
})()

let ProxyImg = ((src) => {
    let img = new Image();
    img.onload = () => {
        myImg.setSrc(img.src);
    }
    return {
        setSrc(src){
            myImg.setSrc('https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg');
            img.src =  src;
        }
    }
})()

imgSrc = 'https://upload.jianshu.io/users/upload_avatars/1413261/a0f9887a-
24f8-408c-bfd1-2975924e8f02.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/80/h/80/format/webp'
ProxyImg.setSrc(imgSrc);
案例小结

可以看出代码优化之后,结构更加清晰。
使用匿名函数自自执行,一方面可以不对外暴露接口与方法
另一方面使得创建dom节点与加载进行异步分离,某种程度上实现代码的解耦。

myImg对象负责创建dom节点,里面的setSrc负责渲染真正图片
代理对象proxyImg负责创建img对象,设置初始图片路径src,等图片onload方法执行之后,便开始将传入的src替换初始图片的src,从而实现图片占位的效果。

2、使用缓存代理实现计算结果的缓存
// 计算乘积
let mult = function(){
    let a = 1;
    for(let i = 0; i < arguments.length; i++){
        a = a * arguments[i];
    }
    console.log(a)
    return a;
}
// mult(1, 2);

// 创建缓存代理的工厂
let createProxyFactory = function(fn){
    let cache = {};
    return function(){
        let args = Array.prototype.join.call(arguments, ','); // '1,2,3,4'
        if(args in cache){
            return cache[args];
        }
        return cache[args] = fn.apply(this, arguments);
    }
}
let proxyMult = createProxyFactory(mult);
proxyMult(1, 2, 3, 4);
// 有了第一次cache对象中的缓存的结果,第二次直接返回
proxyMult(1, 2, 3, 4);

本次案例,第一次执行proxyMult的时候,返回一个function,当传入参数1234调用第一次的时候,缓存了一个计算记过{'1234', 24},当第二次传入同样的参数,便可以从cache对象中找到第一次的计算结果,直接返回即可,这样减少了计算。

案例小结:通过传入高阶函数这种更加灵活的方式,可以为各种计算方法创建缓存代理。现在这些方法被当做参数传入一个专门用于创建缓存代理的工厂中,这样一来,我们就可以为乘法、加法、减法等创建缓存代理。

大家可以思考一下缓存代理 如何用于ajax异步请求数据,同一页的数据理论上只需要去后台 领取一次,这些已经拉去到的数据在某个地方被缓存之后,下次再请求统同一页的时候,便可以直接使用之前的数据。

参考曾参的《JavaScript设计模式与开发实践》

相关文章

  • 前端设计模式

    JS设计模式一:工厂模式jS设计模式二:单例模式JS设计模式三:模块模式JS设计模式四:代理模式JS设计模式五:职...

  • JS设计模式之代理模式

    代理是一个对象,它可以用来控制对本体对象的访问,它与本体对象实现了同样的接口,代理对象会把所有的调用方法传递给本体...

  • js设计模式之代理模式

    假如现在有一个需求是向服务器同步十个checkbox的状态,如果是传统写法的话就是判断checkbox的状态判断选...

  • JS设计模式之代理模式

    定义: 为其他对象提供一种代理以控制对这个对象的访问。何时使用:想在访问一个类时做一些控制。 如何解决:增加中间层...

  • 设计模式之代理模式

    设计模式之代理模式 10分钟看懂动态代理设计模式(升级篇)-对这篇动态代理模式的思路整理 仿JDK实现动态代理逻辑...

  • 代理模式

    设计模式之代理模式 什么是代理模式? 指的事代理对象为其他对象提供代理以控制对被...

  • 2021-11-17 - 学习记录

    适配器模式 - js: 代理模式 - js 组合模式 - js

  • Java设计模式之代理模式

    Java设计模式之代理模式 代理模式 静态代理 动态代理 为什么需要代理 通过代理,我们能够不用知道委托人是谁,而...

  • Java代理模式之JDK动态代理

    了解什么是动态代理模式,可参考Java设计模式之代理模式 简介 JDK动态代理是java.lang.reflect...

  • 设计模式之代理模式2

    设计模式之代理模式运用 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对...

网友评论

    本文标题:JS设计模式之代理模式

    本文链接:https://www.haomeiwen.com/subject/kxsglktx.html