javascript设计模式之代理模式

目录
  • 一. 初识代理模式
  • 二. 代理模式的实现思想
  • 三. 代理模式分类
  • 四. 虚拟代理模式的实际运用
  • 五. 代理的使用意义及要求
  • 六. 总结

一. 初识代理模式

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。它的用处就是当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问。通俗来讲就是,代理是一个中间人,负责在客户和卖家之间传递信息,将没用的信息过滤,将有利于交易成功的信息传递给卖家,从而加大交易的成功率。

二. 代理模式的实现思想

现在我们来通过一个小明给女神送花的例子来实现代理模式。

没有使用代理模式

        let Flower = function () {};
        let xiaomingFirst = {
            sendFlower ( target ) {
                let flower = new Flower();
                target.receiveFlower( flower );
            }
        }
        let A = {
            receiveFlower ( flower ) {
                console.log('收到花')
            }
        }
        xiaomingFirst.sendFlower(A);

使用代理模式重构

设定一个需求AA 为小明的女神,AA 在心情好的时候接受小明花的几率更大,而 B 是 AA 和小明的好朋友,因此小明将花送给 B,让 B 在 AA 心情好时转告自己的心意。

分析:重构后的代码增加了一个新的对象 B , 此时 为 AA 的代理,监听 AA 的好心情,代码中假定5秒后 AA 心情变好,将花送出。

        let xiaomingSencend = {
            sendFlower ( target ) {
                let flower = new Flower();
                target.receiveFlower( flower );
            }
        }
        let AA = {
            receiveFlower () {
                console.log('收到花');
            },
            listenGoodMood ( fn ) {
                setTimeout(()=>{
                    fn();
                }, 5000);
            }
        }
        let B = {
            receiveFlower ( flower ) {
                AA.listenGoodMood( ()=>{
                    AA.receiveFlower( flower );
                } );
            }
        }
        xiaomingSencend.sendFlower(B);

三. 代理模式分类

上述代码中代理模式可能显得不那么重要,但是体现了代理的思想,假如女神有一些要求,给他送花的男生必须帅而有钱,但又不能显得那么势力,因此代理可以帮其过滤掉这些不符合要求的男生,减少自己的许多麻烦,还能保持自己的美好形象这就是代理的用处。再者说,买一朵花很昂贵,而不是单单 new 这么简单,男生不想浪费自己的钱,因此想先确定女神是否接受自己的花,便让代理帮忙询问,如果女神接受则让代理帮忙买一朵送给女神,这样减少了男生的损失但也达成了目的,这便引出了以下两种代理模式。

  • 保护代理:本体的要求直接在代理中实现,过滤掉不符合的要求的访问者对本体的请求
  • 虚拟代理:将一些开销很大的操作等到准备向本体请求时候再实现(主要用于实际开发)

四. 虚拟代理模式的实际运用

1. 虚拟代理实现图片预加载

分析:先加载本地图片,然后开始发起请求获取图片,当图片加载获取成功后,再调用 myImage 将图片替换预加载时显示的图片。

    let myImage = function () {
        let img = document.createElement('img');
        document.body.appendChild(img);
        return {
            setSrc ( src ) {
                img.src = src;
            }
        }
    }();
    proxyImage = function () {
        let img = new Image;
        img.onload = function () {
            myImage.setSrc( this.src );
        }
        return {
            setProxyImage( src ) {
                myImage.setSrc("https://img.zcool.cn/community/01e2115d5d5c7da80120695c137bfb.jpg@1280w_1l_2o_100sh.jpg"); // 此处为加载 loading 图片,用来占位,本地图片(作者使用网络图片)
                img.src = src;
            }
        }
    }();
    proxyImage.setProxyImage("https://img.zcool.cn/community/01a5d45543cd170000019ae94fc087.jpg@1280w_1l_2o_100sh.jpg");

 2. 缓存代理

分析:在代理中将本体计算的结果进行缓存,如果下次再遇到同样的请求,直接从缓存中获取,减少对本体的访问,减少性能消耗。

    let myImage = function () {
        let img = document.createElement('img');
        document.body.appendChild(img);
        return {
            setSrc ( src ) {
                img.src = src;
            }
        }
    }();
    proxyImage = function () {
        let img = new Image;
        img.onload = function () {
            myImage.setSrc( this.src );
        }
        return {
            setProxyImage( src ) {
                myImage.setSrc("https://img.zcool.cn/community/01e2115d5d5c7da80120695c137bfb.jpg@1280w_1l_2o_100sh.jpg"); // 此处为加载 loading 图片,用来占位,本地图片(作者使用网络图片)
                img.src = src;
            }
        }
    }();
    proxyImage.setProxyImage("https://img.zcool.cn/community/01a5d45543cd170000019ae94fc087.jpg@1280w_1l_2o_100sh.jpg");

3. 虚拟代理合并 Http 请求

使用场景:点击复选框向服务器发起请求同步文件,每次点击复选框便发起一次请求,造成巨大网络开销,此时我们优化的方式为,将想同步的文件缓存下来,在 3 秒后通过一次请求发送到服务器。

    <input type="checkbox" >1
    <input type="checkbox" >2
    <input type="checkbox" >3
    <input type="checkbox" >4
    <input type="checkbox" >5
    <input type="checkbox" >6
    <input type="checkbox" >7
    <input type="checkbox" >8
    <script>
        // 同步文件
        let synchronousFile = function ( id ) {
            console.log("开始同步文件" + id);
        }
        // 代理实现同步文件
        let proxySynchronousFile = function ( ) {
            let cache = [];
            let time;
            return function ( id ) {
                cache.push( id );
                if( time ) {
                    return;
                }
                time = setInterval(() => {
                    synchronousFile(cache.join(','));
                    clearInterval(time);
                    time = null;
                    cache.length = 0;
                }, 3000);
            }
        }()
        // 添加点击执行
        let checkboxList = document.getElementsByTagName('input');
        for(let i = 0, l = checkboxList.length; i < l; i++) {
            checkboxList[i].onclick = function() {
                if( this.checked === true ) {
                    proxySynchronousFile(i+1);
                }
            }
        }

五. 代理的使用意义及要求

  • 意义:首先我们引入面向对象设计原则,单一职责原则,一个对象应该尽可能少的承担职责,最好是一个,如果承担职责过多,会提高代码的耦合度,从而导致脆弱和低内聚的设计。当变化发生,设计可能遭到意外破坏,即使实现同样需求可以将代码封装到一个函数中,但是最好的处理措施是引入代理模式
  • 要求:代理和本体接口要一致,在任何使用本体地方都可以用代理来代替

六. 总结

代理模式包括很多小模块,最常用的为缓存代理 和 虚拟代理,虽然代理模式非常有用,但我们再编写业务代码时不需要预先猜测是否需要使用代理模式,到发现不方便直接访问某个对象,真正使用时再编写也不迟。

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • JavaScript设计模式之代理模式实例分析

    本文实例讲述了JavaScript设计模式之代理模式.分享给大家供大家参考,具体如下: 代理模式的定义,代理是一个对象(proxy)用它来控制目标对象的访问.为此他要是先与目标对象相同的接口,但是他不同于装饰者模式,它对目标对象不进行任何修改,它的目的在于延缓"复杂"对象的初始化时间.这样可以在用到这个目标对象的时候再初始化他(对于单例来讲更是重要). 代理模式有两种分类: (1)普通代理 (2)惰性代理 具体看下面的例子 第一,普通代理模式 步骤一,接口检验文件的引用 //定义一个静

  • JavaScript设计模式之代理模式详解

    代理模式是非常常见的模式,比如我们使用的VPN工具,明星的经纪人,都是代理模式的例子.但是,有人会疑问,明明可以直接访问对象,为什么中间还要加一个壳呢?这也就说到了代理模式的好处.在我看来,代理模式最大的好处,就是在不动原有对象的同时,可以给原有对象增加一些新的特性或者行为. /** * pre:代理模式 * 小明追求A,B是A的好朋友,小明比较腼腆,不好意思直接将花交给A, * 于是小明将花交给B,再由B交给A. */ //----------- 示例1 --------- // 不使用代理

  • 详解javascript设计模式三:代理模式

    代理模式是一种对程序对象进行控制性访问的一类解决方案. 引入代理模式,其实是为了实现单一职责的面向对象设计原则. 单一职责其实就是指在一个类中(js中通常指对象和函数等),应仅有一个引起它变化的原因.这样会帮助程序设计具有良好的健壮和高内聚特性,从而当变化发生时,程序设计会尽量少的受到意外破坏. 代理模式有多种方法,保护代理.远程代理.虚拟代理.缓存代理等. 但在javascript中,代理模式最常用到的两种方法是虚拟代理和缓存代理. 虚拟代理 在理解虚拟代理时,可以将其想象为一个经纪人,客户程

  • javascript设计模式之订阅者模式

    目录 一. 初识代理模式 二. 代理模式的实现思想 三. 代理模式分类 四. 虚拟代理模式的实际运用 五. 代理的使用意义及要求 六. 总结 一. 初识代理模式 代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问.它的用处就是当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问.通俗来讲就是,代理是一个中间人,负责在客户和卖家之间传递信息,将没用的信息过滤,将有利于交易成功的信息传递给卖家,从而加大交易的成功率. 二. 代理模式的实现思想 现在我们

  • JavaScript设计模式学习之代理模式

    概述 代理模式属于设计模式中结构型的设计模式: 定义: 顾名思义就是为一个对象提供一个代用品或占位符,以便控制对它的访问! 白话解释: 很多明星都是有经纪人的,如果要联系明显进行商演或者开演唱会之类的商业活动通过是需要先跟经纪人取得联系的,跟经纪人谈好了合作事宜之后经纪人再转达给某明星,然后某明星才会去参加活动:同样租房也是一个同样的道理,我们不管是租房还是买房,第一反应肯定是找链家这类的平台,因为我们只需要跟链家进行沟通,而链家去跟房东沟通,省去了我们直接和房东沟通的步骤:因为链家就是一个代理

  • JavaScript设计模式之代理模式简单实例教程

    本文实例讲述了JavaScript设计模式之代理模式.分享给大家供大家参考,具体如下: 一.代理模式概念 代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象控制具体对象的引用.代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西. 解释:房屋中介,可以代理帮助卖家把房子卖给买家,这中间卖家说要卖的价钱就可以了,买家也可以提出自己要买的房型,中介可以帮忙处理中间环节.最后达成

  • 学习JavaScript设计模式之代理模式

    明星都有经纪人作为代理.如果请明星办一场商演,只能联系其经纪人,经纪人会把商演的细节和报酬谈好,再把合同交给明星签. 一.定义 代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问. 代理分为:保护代理和虚拟代理 保护代理:用于控制不同权限的对象对目标对象的访问,在JavaScript中很难判断谁访问了某个对象,所以保护代理很难实现. 二.图片预加载(最常见的虚拟代理应用场景) 图片预加载是一种常用技术,如果直接给某个img标签节点设置src属性,由于图片过大或者网络不佳,图片的位置往

  • JavaScript设计模式之代理模式介绍

    代理模式说明 说明:顾名思义就是用一个类来代替另一个类来执行方法功能,这个模式跟装饰模式有点相似,不一样的是,代理模式是代替客户初始化被代理对象类,而装饰模式采用接口或初装饰者参数引用的方式来执行的. 在动态面向对象语言里,代理模式即起到控制修饰被代理类的作用,也对被代理类起到了充分的隐藏保护作用:被代理类只到我们需要时,才被间接初始化调用: 场景描述: 很常见到的就是租房子的例子,房客要租房子,房东要把房子租出去,但是房客跟房东都没怎么有空找房子或在家等着有人看房子,就一同去找房屋中介.房东把

  • javascript设计模式之代理模式

    目录 一. 初识代理模式 二. 代理模式的实现思想 三. 代理模式分类 四. 虚拟代理模式的实际运用 五. 代理的使用意义及要求 六. 总结 一. 初识代理模式 代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问.它的用处就是当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问.通俗来讲就是,代理是一个中间人,负责在客户和卖家之间传递信息,将没用的信息过滤,将有利于交易成功的信息传递给卖家,从而加大交易的成功率. 二. 代理模式的实现思想 现在我们

  • js设计模式之代理模式及订阅发布模式实例详解

    本文实例讲述了js设计模式之代理模式及订阅发布模式.分享给大家供大家参考,具体如下: 为啥将两种模式放在一起呢?因为这样文章比较长啊. 写博客的目的我觉得首要目的是整理自己的知识点,进而优化个人所得知识体系.知识成为个人的知识,就在于能够用自己的话表达同一种意义. 本文是设计模式系列文章的第二篇文章,第一篇:. 1,代理模式,只是学习了虚拟代理以及缓存代理,具体案例 1)虚拟代理 //业务代码 var myImage = (function() { var imgNode = document.

  • javascript设计模式之Adapter模式【适配器模式】实现方法示例

    本文实例讲述了javascript设计模式之Adapter模式.分享给大家供大家参考,具体如下: 所谓Adapter模式就是适配器模式,主要是指使两个原本没有关联的类结合一起使用. JS实现Adapter模式示例如下: <!DOCTYPE html> <html> <head> <title></title> <script type="text/javascript" src="json.js"&g

  • Python设计模式之代理模式实例

    翻墙常用的方式就是使用代理(Proxy),其基本过程如下: 浏览器<-->代理服务器<-->服务器 如果浏览器请求不到服务器,或者服务器无法响应浏览器,我们可以设定将浏览器的请求传递给代理服务器,代理服务器将请求转发给服务器.然后,代理服务器将服务器的响应内容传递给浏览器.当然,代理服务器在得到请求或者响应内容的时候,本身也可以做些处理,例如缓存静态内容以加速,或者说提取请求内容或者响应内容做些正当或者不正当的分析.这种翻墙方式,就是设计模式中代理模式(Proxy Pattern)

  • 学习JavaScript设计模式之迭代器模式

    迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. JavaScript中的Array.prototype.forEach 一.jQuery中的迭代器 $.each([1, 2, 3], function(i, n) { console.log("当前下标为:"+ i + " 当前元素为:"+ n ); }); 二.实现自己的迭代器 var each = function(ary, callback) { for(var i

随机推荐