JavaScript设计模式 代理模式

一.生活场景

明星都有经纪人作为代理。如果想请明星来办一场商业演出,只能联系他的经纪人。经纪人会把商业演出的细节和报酬都谈好之后,再把合同交给明星签。

二.定义

代理模式 :为一个对象提供一个代用品或占位符,以便控制对它的访问。

  • 虚拟代理: 把一些开销很大的对象,延迟到真正需要它的时候才去创建。
  • 缓存代理: 缓存代理可以为一些开销大的运算结果提供暂时的存储,在下次运算时,如果传递进来的参数跟之前一致,则可以直接返回前面存储的运算结果。

三.应用场景

1.图片预加载(利用虚拟代理)

当图片过大或者网络不佳时,图片预加载是一种常用的技术,如果直接给某个 img 标签节点设置 src 属性,,图片的位置往往有段时间会是一片空白。常见的做法是先用一张loading 图片占位,然后用异步的方式加载图片,等图片加载好了再把它填充到 img 节点里。

  • 不用代理实现:
var myImage = (function () {
    var imgNode = document.createElement('img');
    document.body.appendChild(imgNode);
    return {
        setSrc: function (src) {
            imgNode.src = src;
        }
    }
})();
myImage.setSrc('http://jsmeng.top/music/photo/k/000GGDys0yA0Nk.jpg');
  • 虚拟代理实现
var myImage = (function () {
    var imgNode = document.createElement('img');
    document.body.appendChild(imgNode);
    return {
        setSrc: function (src) {
            imgNode.src = src;
        }
    }
})();
var proxyImage = (function () {
    var img = new Image;
    img.onload = function () {
        myImage.setSrc(this.src);
    }
    return {
        setSrc: function (src) {
            myImage.setSrc('file://C:/Users/svenzeng/Desktop/loading.gif');
            img.src = src;
        }
    }
})();
proxyImage.setSrc('http://jsmeng.top/music/photo/k/000GGDys0yA0Nk.jpg');

运用代理模式来实现图片预加载,巧妙地将创建图片与预加载逻辑分离,并且在未来如果不需要预加载,只要改成请求本体代替请求代理对象就行。

2.计算乘积(利用缓存代理)

当一些计算非常耗费性能和时间时,我们可以缓存每次计算的结果,从而避免相同运算带来的时间浪费。

/***********************创建一个求乘积的函数**************************/
var mult = function () {
    console.log('开始计算乘积');
    var a = 1;
    for (var i = 0, l = arguments.length; i < l; i++) {
        a = a * arguments[i];
    }
    return a;
};
/***********************缓存代理函数**************************/
var proxyMult = (function () {
    var cache = {};
    return function () {
        var args = Array.prototype.join.call(arguments, ',');
        if (args in cache) {
            return cache[args];
        }
        return cache[args] = mult.apply(this, arguments);
    }
})();
proxyMult(1, 2, 3, 4); // 输出:24
proxyMult(1, 2, 3, 4); // 输出:24

四.总结

对于开发者而言,代理只是在本体之前加了一层处理,并不影响本地的算法,当我们不需要代理时,只需要注释代理代码,直接访问本体就可。

对于用户来说,代理的过程是透明的,用户并不清楚代理和本体的区别,这样做有两个好处。

  • 用户可以放心地请求代理,他只关心是否能得到想要的结果。
  • 在任何使用本体的地方都可以替换成使用代理。

我们在编写业务代码的时候,往往不需要去预先猜测是否需要使用代理模式。当真正发现不方便直接访问某个对象的时候,再编写代理也不迟。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值