JavaScript设计模式_03_代理模式

代理模式是非常常见的模式,比如我们使用的VPN工具,明星的经纪人,都是代理模式的例子。但是,有人会疑问,明明可以直接访问对象,为什么中间还要加一个壳呢?这也就说到了代理模式的好处。在我看来,代理模式最大的好处,就是在不动原有对象的同时,可以给原有对象增加一些新的特性或者行为。

/**
 * pre:代理模式
 * 小明追求A,B是A的好朋友,小明比较腼腆,不好意思直接将花交给A,
 * 于是小明将花交给B,再由B交给A.
 */
//----------- 示例1 ---------
// 不使用代理
var Flower = function() {};
var xiaoming = {
    sendFlower: function(target) {
        var flower = new Flower();
        target.receiveFlower(flower);
    }
};
var A = {
    receiveFlower: function(flower) {
        console.log("收到花:" + flower);
    }
};
xiaoming.sendFlower(A);

// ----------- 示例2 --------------
// 使用代理1
var Flower = function() {};
var xiaoming = {
    sendFlower: function(target) {
        var flower = new Flower();
        B.receiveFlower(flower);
    }
};
var B = {
    receiveFlower: function(flower) {
        A.receiveFlower(flower);
    }
};
var A = {
    receiveFlower: function(flower) {
        console.log("收到花:" + flower);
    }
};
xiaoming.sendFlower(B);
//------------- 示例3 ---------------
// 使用代理2
var Flower = function() {};
var xiaoming = {
    sendFlower: function(target) {
        var flower = new Flower();
        B.receiveFlower(flower);
    }
};
var B = {
    receiveFlower: function(flower) {
        A.listenGoodMood(function() {
            A.receiveFlower(flower);
        });
    }
};
var A = {
    receiveFlower: function(flower) {
        console.log("收到花:" + flower);
    },
    listenGoodMood: function(fn) {
        setTimeout(function() {
            fn.apply(this, arguments);
        }, 2000);
    }
};
xiaoming.sendFlower(B);
// ---------- 示例4 ---------------
/*
 * 【代理模式用处】:虚拟代理
 * 这里以加载图片为例,我们都知道当网络不畅以及图片过大时,图片加载都比较慢,
 * 为了更好的用户体验,我们都会在原图片未加载完成前,加上loading图片。
 * */
//--4 _01未使用代理--
var myImage = (function() {
    var imgNode = document.createElement("img");
    document.body.appendChild(imgNode);
    return {
        setSrc: function(src) {
            this.imgNode.src = src;
        }
    }
})();
myImage.setSrc("xxx");
//--4_02使用代理--
var proxyMyImage = (function() {
    var img = new Image();
    img.onload = function() {
        myImage.setSrc(this.src);
    };
    return {
        setSrc: function(src) {
            myImage.setSrc("loading.jpg");
            img.src = src;
        }
    }
})();
proxyMyImage.setSrc("xxx");
/*
 * [注]:这里可以看到代理模式的好处:在不改变原有接口的同时,可以为系统添加新的行为。
 */
//--------- 示例5---------------
/*
 * 【代理模式用处】:合并http请求
 * 这里以选择文件同步为例。
 * 以往用户同步文件,在用户选中的时候就触发,这种方法做到了实时性,但无疑增加了网络的开销。
 * 实际在使用的过程中,往往并不需要立刻就同步。
 * 以下通过代理模式,将在用户选中文件2秒后进行同步请求。
 * */
// --- 包含一段html代码,请自行添加到一个文件中 ------
<html>
    <body>
        <button id="input">点我上传</button>
        <input type="checkbox" id="1"></input>1
        <input type="checkbox" id="2"></input>2
        <input type="checkbox" id="3"></input>3
        <input type="checkbox" id="4"></input>4
        <input type="checkbox" id="5"></input>5
        <input type="checkbox" id="6"></input>6
        <input type="checkbox" id="7"></input>7
        <input type="checkbox" id="8"></input>8
        <input type="checkbox" id="9"></input>9
    </body>
</html>
// -- 上传文件 --
var synchronizeFile = function(id) {
    console.log("开始同步文件:" + id);
};
var proxySynchronizeFiles = (function() {
    var fileCache = [],
        timer;
    return function(id) {
        fileCache.push(id);
        if(timer) {
            return;
        }
        timer = setTimeout(function() {
            synchronizeFile(fileCache.join(","));
            clearTimeout(timer);
            timer = null;
            checkArr.length = 0;
        }, 2000);
    }
})();
var checkArr = document.getElementsByTagName("input");
for(var i = 0, c; c = checkArr[i++];) {
    c.onclick = function() {
        if(this.checked == true) {
            proxySynchronizeFiles(this.id);
        }
    }
}
// ------------ 示例6 -----------------
/*
 * 【代理模式用处】:缓存代理
 *  以计算器为例,比如计算某些数的乘积,当参数重复时,我们希望不用重复计算,直接返回结果。
 *  以下用到代理模式做缓存。
 */
var mult = function() {
    if(!arguments) {
        console.log("请输入参数");
        return;
    }
    var a = 1;
    for(var i = 0, b; b = arguments[i++];) {
        a = a * b;
    }
    return a;
};

var proxyMult = (function() {
    var cache = {};
    return function() {
        var str = Array.prototype.join.call(arguments, ",");
        if(str in cache) {
            console.log("重复return.");
            return cache[str];
        }
        return cache[str] = mult.apply(this, arguments);
    }
})();

console.log(proxyMult(2, 3, 4));
console.log(proxyMult(2, 3, 4));
//------------ 示例7 --------------
/*
 * 缓存代理升级 - 通用版计算
 *
 */
var mult = function() {
    if(!arguments) {
        return;
    }
    var t = 1;
    for(var i = 0, a; a = arguments[i++];) {
        t = t * a;
    }
    return t;
};
var plus = function() {
    if(!arguments) {
        return;
    }
    var t = 0;
    for(var i = 0, a; a = arguments[i++];) {
        t += a;
    }
    return t;
};
var createProxyCaculate = function(fn) {
    var cache = {};
    return function() {
        var str = Array.prototype.join.call(arguments, ",");
        if(str in cache) {
            console.log(str);
            return cache[str];
        }
        return cache[str] = fn.apply(this, arguments);
    }
};
var proxyMult = createProxyCaculate(mult);
var proxyPlus = createProxyCaculate(plus);
console.log(proxyMult(2, 3, 4));
console.log(proxyMult(2, 3, 4));

作者:『Stinchan』

出处:http://www.cnblogs.com/stinchan/p/6971277.html

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

时间: 2024-10-06 08:05:49

JavaScript设计模式_03_代理模式的相关文章

JavaScript设计模式之代理模式

一.代理模式概念 代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象控制具体对象的引用.代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西. 解释:房屋中介,可以代理帮助卖家把房子卖给买家,这中间卖家说要卖的价钱就可以了,买家也可以提出自己要买的房型,中介可以帮忙处理中间环节.最后达成买卖.中介可以同时代理很多房屋买卖,并且可以代理租房事宜. 二.代理模式的作用和注意事项

Android设计模式之代理模式 Proxy

一.概述 代理模式也是平时比较常用的设计模式之一,代理模式其实就是提供了一个新的对象,实现了对真实对象的操作,或成为真实对象的替身.在日常生活中也是很常见的.例如A要租房,为了省麻烦A会去找中介,中介会替代A去筛选房子,A坐享中介筛选的结果,并且交房租也是交给中介,这就是一个典型的日常生活中代理模式的应用.平时打开网页,最先开到的一般都是文字,而图片等一些大的资源都会延迟加载,这里也是使用了代理模式. 代理模式的组成: Abstract Subject:抽象主题-声明真实主题和代理主题共同的接口

【设计模式】代理模式

代理模式在所需对象和用户代码之间增加了一层对象,这个对象被称为代理.用户代码只需要直接操作代理对象即可.著名的代理模式的例子就是引用计数指针对象,它使得我们对真实对象的操作都需要经过引用计数指针对象.下面是用C++写的一个运用了代理模式的例子. #include <iostream> #include <string> using namespace std; // 作为接口的抽象基类 class Subject { public: virtual void DoAction()

设计模式之代理模式(Proxy)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

【大话设计模式】——代理模式

对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate 的继承映射可以理解持久化类之间的继承关系.例如:人和学生之间的关系.学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到. Hibernate支持三种继承映射策略: 使用 subclass 进行映射:将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态. 使用 joined-subclass 进行映射: 对于继承关系中的子类使用同一个表

设计模式之代理模式 c++实现以及详解

proxy模式 <1> 作用: 为其他对象提供一种代理以控制对这个对象的访问. <2> 代理模式的应用场景: 如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法: 1.修改原有的方法来适应.这样违反了"对扩展开放,对修改关闭"的原则. 2.就是采用一个代理类调用原有的方法,且对产生的结果进行控制.这种方法就是代理模式. 使用代理模式,可以将功能划分的更加清晰,有助于后期维护! <3> 结构图 代理类,含有一个指向RealSubject

JAVA设计模式之代理模式

学编程吧JAVA设计模式之代理模式发布了,欢迎通过xuebiancheng8.com来访问 一.概述 给某一个对象提供一个代理,并由代理对象来完成对原对象的访问.代理模式是一种对象结构型模式. 二.适用场景 当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口. 三.UML类图 四.参与者 1.接口类:Subject 它声明了真实访问者和代理访问者的共同接口,客户端通常需要针对接口角色进行编程. 2.代理类

JAVA设计模式(3)----代理模式

1.  什么是代理模式?Proxy Pattern 代理模式定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 通俗的讲,代理模式就是我很忙没空理你,你要想找我可以先找我的代理人,代理人和被代理人继承同一个接口.代理人虽然不能干活,但是被代理的人可以干活. 这个例子中有水浒传中的这么几个人:名垂青史的潘金莲,王婆,西门大官人.西门庆想要找潘金莲,需要找王婆做代理.首先定义一个接口:Kin

设计模式之代理模式20170724

结构型设计模式之代理模式: 一.含义 代理模式也叫做委托模式,其定义如下: 为其他对象提供一种代理以控制对这个对象的访问. 二.代码说明 1.主要有两个角色 1)具体主题角色 也叫做委托角色.被代理角色.它是业务逻辑的具体执行者. 2)代理主题角色 也叫做委托类.代理类.它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作. 一个代理类可以代理多个被委托者或被代理者. 2.在用C实现过程中也是参考这种思想,以游戏代理场