美文网首页
javascript设计模式( 三)代理模式

javascript设计模式( 三)代理模式

作者: Sccong | 来源:发表于2017-08-03 16:22 被阅读0次

代理模式,顾名思义,就是A要对C做一件事情,让B帮忙做(怎么听起来怪怪的)。

// A
var A = function(){
    this.talk = function(){
        console.log("能带我打dota2吗");
    }
};
//C
var C= function(){
    this.B = new B();
    this.talk = function(){
        console.log("一个人打dota2好没意思啊");
        this.B.talk();
    }
}
//我
var B = function(){
    this.A = new A();
    this.talk = function(){
        console.log("A 让我问你");
        this.A.talk();
    }
}
//执行
new C().talk();
//结果
/**
 * 一个人打dota2好没意思啊
 * A 让我问你
 * 能带我打dota2吗
 */

下面写几个常见的使用代理模式的例子

在网页开发中,图片的预加载是一种比较常用的技术,如果直接给img标签节点设置src属性的话,如果图片比较大的话,或者网速相对比较慢的话,那么在图片未加载完之前,图片会有一段时间是空白的场景,这样对于用户体验来讲并不好,那么这个时候我们可以在图片未加载完之前我们可以使用一个loading加载图片。

//使用代理模式的写法
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("http://img.lanrentuku.com/img/allimg/1212/5-121204193Q9-50.gif");
            img.src = src;
        }
    }
})();

// 调用方式
ProxyImage.setSrc("https://img.alicdn.com/tps/i4/TB1b_neLXXXXXcoXFXXc8PZ9XXX-130-200.png");

如上代码所示,其中myImage 函数只负责做一件事,创建img元素加入到页面中,其中的加载loading图片交给代理函数ProxyImage 去做,当图片加载成功后,代理函数ProxyImage 会通知及执行myImage 函数的方法,同时当以后不需要代理对象的话,我们直接可以调用本体对象的方法即可。
代理模式还可以用在需要多次提交数据的地方,比如,有表格数据,每一条数据前面有复选框按钮,当点击复选框按钮时候,需要获取该id后需要传递给给服务器发送ajax请求,服务器端需要记录这条数据,去请求,如果我们每当点击一下向服务器发送一个http请求的话,对于服务器来说压力比较大,网络请求比较频繁,但是如果现在该系统的实时数据不是很高的话,我们可以通过一个代理函数收集一段时间内(比如说2-3秒)的所有id,一次性发ajax请求给服务器,相对来说网络请求降低了, 服务器压力减少了;

// 本体函数
var mainFunc = function(ids) {
    console.log(ids); // 即可打印被选中的所有的id
    // 再把所有的id一次性发ajax请求给服务器端
};
// 代理函数 通过代理函数获取所有的id 传给本体函数去执行
var proxyFunc = (function(){
    var cache = [],  // 保存一段时间内的id
        timer = null; // 定时器
    return function(checkboxs) {
        // 判断如果定时器有的话,不进行覆盖操作
        if(timer) {
            return;
        }
        timer = setTimeout(function(){
            // 在2秒内获取所有被选中的id,通过属性isflag判断是否被选中
            for(var i = 0,ilen = checkboxs.length; i < ilen; i++) {
                if(checkboxs[i].hasAttribute("isflag")) {
                    var id = checkboxs[i].getAttribute("data-id");
                    cache[cache.length] = id;
                }
            }
            mainFunc(cache.join(',')); // 2秒后需要给本体函数传递所有的id
            // 清空定时器
            clearTimeout(timer);
            timer = null;
            cache = [];
        },2000);
    }
})();
var checkboxs = document.getElementsByClassName("j-input");
for(var i = 0,ilen = checkboxs.length; i < ilen; i+=1) {
    (function(i){
        checkboxs[i].onclick = function(){
            if(this.checked) {
                // 给当前增加一个属性
                this.setAttribute("isflag",1);
            }else {
                this.removeAttribute('isflag');
            }
            // 调用代理函数
            proxyFunc(checkboxs);
        }

    })(i);
}

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

// 计算乘积
var mult = function(){
    var a = 1;
    for( var i = 0, l = arguments.length; i < l; i++){
        a = a * arguments[i];
    }
    return a;
};
// 计算加和
var plus = function () {
  var a = 0;
    for( var i = 0, l = arguments.length; i < l; i++ ){
        a += arguments[i];
    }
    return a;
};
// 创建缓存代理的工厂
var createProxyFactory = function( fn ){
    var cache = {}; // 缓存 - 存放参数和计算后的值
    return function(){
        var args = Array.prototype.join.call(arguments, "-");
        if( args in cache ){ // 判断出入的参数是否被计算过
            console.log( "使用缓存代理" );
            return cache[args];
        }
        return cache[args] = fn.apply( this, arguments );
    }
};
// 创建代理
var proxyMult = createProxyFactory( mult ),
    proxyPlus = createProxyFactory( plus );

console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 24
console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 缓存代理 24
console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 10
console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 缓存代理 10

相关文章

  • javascript设计模式( 三)代理模式

    代理模式,顾名思义,就是A要对C做一件事情,让B帮忙做(怎么听起来怪怪的)。 下面写几个常见的使用代理模式的例子 ...

  • JavaScript 设计模式(三):代理模式

    代理模式:为一个对象提供一个代用品或占位符,以便控制它的访问。 当我们不方便直接访问某个对象时,或不满足需求时,可...

  • JavaScript设计模式(三) 代理模式

    我们来回顾上一章策略模式留下的问题: 假设公司的绩效等级分为 A,B,C,D,E 年终奖对应的绩点为 2,1.8,...

  • JavaScript设计模式四(代理模式)

    JavaScript设计模式四(代理模式) 代理模式的定义: 代理模式是为一个对象提供一个代用品或者占位符,以便对...

  • Javascript设计模式-代理模式

    特点 1.使用者无法直接访问目标对象 2.使用者和目标对象之间加一层代理,通过代理来授权和控制 例如:访问gith...

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

    代理模式 代理的概念 由于一个对象不能直接引用另一个对象,所以需要通过代理对象在这两个对象之间起到中介的作用 以上...

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

    代理模式属于设计模式中结构型的设计模式; 定义:顾名思义就是为一个对象提供一个代用品或占位符,以便控制对它的访问!...

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

    代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。 代理模式是一种非常有意义的模式,在生活中可以找到...

  • JavaScript设计模式--代理模式

    一、定义 代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问。代理分为:保护代理和虚拟代理保护代理:用...

  • 前端设计模式

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

网友评论

      本文标题:javascript设计模式( 三)代理模式

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