代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理之后,再把请求转交给本体对象。

代理模式类图:

在上面类图中,代理模式所涉及的角色有三个:

抽象主题角色(Person):声明了真实主题和代理主题的公共接口,这样一来在使用真实主题的任何地方都可以使用代理主题。

代理主题角色(Friend):代 理主题角色内部含有对真实主题的引用,从而可以操作真实主题对象;代理主题角色负责在需要的时候创建真实主题对象;代理角色通常在将客户端调用传递到真实 主题之前或之后,都要执行一些其他的操作,而不是单纯地将调用传递给真实主题对象。例如这里的PreBuyProduct和PostBuyProduct 方法就是代理主题角色所执行的其他操作。

真实主题角色(RealBuyPerson):定义了代理角色所代表的真是对象。

附:在实际开发过程中,我们在客户端添加服务引用的时候,在客户程序中会添加一些额外的类,在客户端生成的类扮演着代理主题角色,我们客户端也是直接调用这些代理角色来访问远程服务提供的操作。这个是远程代理的一个典型例子。

先看一下C#的代理模式:

namespace 代理模式
{
class Program
{
static void Main(string[] args)
{
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.Name = "李娇娇"; Proxy daili = new Proxy(jiaojiao); daili.GiveDolls();
daili.GiveFlowers();
daili.GiveChocolate(); Console.Read();
}
} //送礼物
interface GiveGift
{
void GiveDolls();
void GiveFlowers();
void GiveChocolate();
} class Proxy : GiveGift
{
Pursuit gg;
public Proxy(SchoolGirl mm)
{
gg = new Pursuit(mm);
} public void GiveDolls()
{
gg.GiveDolls();
} public void GiveFlowers()
{
gg.GiveFlowers();
} public void GiveChocolate()
{
gg.GiveChocolate();
}
} class Pursuit : GiveGift
{
SchoolGirl mm;
public Pursuit(SchoolGirl mm)
{
this.mm = mm;
}
public void GiveDolls()
{
Console.WriteLine(mm.Name + " 送你洋娃娃");
} public void GiveFlowers()
{
Console.WriteLine(mm.Name + " 送你鲜花");
} public void GiveChocolate()
{
Console.WriteLine(mm.Name + " 送你巧克力");
}
} class SchoolGirl
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
}

js模拟高级语言的代理模式:

var SchoolGirl = function(name){
this.name = name;
}; var Pursuit = function(mm){
this.mm = mm;
};
Pursuit.prototype.giveDolls = function(){
alert(this.mm.name + '送你洋娃娃');
};
Pursuit.prototype.giveFlowers = function(){
alert(this.mm.name + '送你鲜花');
};
Pursuit.prototype.giveChocolate = function(){
alert(this.mm.name + '送你巧克力');
}; var Proxy = function(mm){
this.gg = new Pursuit(mm);
};
Proxy.prototype.giveDolls = function(){
this.gg.giveDolls();
};
Proxy.prototype.giveFlowers = function(){
this.gg.giveFlowers();
};
Proxy.prototype.giveChocolate = function(){
this.gg.giveChocolate();
}; //调用:
var jiaojiao = new SchoolGirl();
jiaojiao.name = "李娇娇"; var daili = new Proxy(jiaojiao); daili.giveDolls();
daili.giveFlowers();
daili.giveChocolate();

js语言特性的代理模式:

var Flower = function(){};

    var Pursuit = {
sendFlower:function(target){
var flower = new Flower();
target.receiveFlower(flower);
}
}; var Proxy = {
sendFlower:function(target){
Pursuit.sendFlower(target);
}
}; var SchoolGirl = {
receiveFlower:function(flower){
console.log('收到花' + flower);
}
}; //调用:
Proxy.sendFlower(SchoolGirl);

js虚拟代理实现图片预加载:

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://imgcache.qq.com/music/photo/k/000GGDys0yAonk.jpg');

js缓存代理实现计算器:

//计算乘积
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 = a + arguments[i];
}
return a;
}; //创建缓存代理工厂
var createProxyFactory = function(fn){
var cache = {};
return function(){
var args = [].join.call(arguments,',');
if(args in cache){
return cache[args];
}
return cache[args] = fn.apply(this,arguments);
}
}; //调用:
var proxyMult = createProxyFactory(mult),
proxyPlus = createProxyFactory(plus); alert(proxyMult(1,2,3,4)); //
alert(proxyMult(1,2,3,4)); //
alert(proxyPlus(1,2,3,4)); //
alert(proxyPlus(1,2,3,4)); //

总结:代理模式包括许多小分类,在js开发中最常用的是虚拟代理和缓存代理。虽然代理模式非常有用,但我们在编写业务的时候,往往不需要去预先猜测是否需要使用代理模式。当真正发现不方便直接访问某个对象的时候,再编写代理也不迟。

js代理模式的更多相关文章

  1. JS 代理模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. JS代理模式实现图片预加载

    ---恢复内容开始--- 刚刚说了懒加载,现在我们来搞搞预加载吧 预加载的核心: 图片等静态资源在使用前提前请求. 资源后续使用可以直接从缓存中加载,提升用户体验. 几个误区: 预加载不是为了减少页面 ...

  3. js设计模式系列之(一)请节约你的请求-代理模式

    What’s the proxy pattern? 代理模式其实就是将违反单一性原则的类给抽离出来,尽量满足开放和封闭的原则. 相当于一个类的行为只是一种,但是你可以给这个类添加额外的行为.比如: 一 ...

  4. JS设计模式(3)代理模式

    什么是代理模式? 情景:小明追女生 A 非代理模式:小明 =花=> 女生A 代理模式:小明 =花=> 让女生A的好友B帮忙 =花=> 女生A 定义:为其他对象提供一种代理以控制对这个 ...

  5. js设计模式——1.代理模式

    js设计模式——1.代理模式 以下是代码示例 /*js设计模式——代理模式*/ class ReadImg { constructor(fileName) { this.fileName = file ...

  6. js设计模式总结-代理模式

    代理模式 解决哪一类问题 从字面意思上理解,代理模式解决对一个对象的直接访问,这种直接访问可能是"不方便"的,所谓"不方便"可能是直接访问成本比较大(在前端领域 ...

  7. 大熊君说说JS与设计模式之------代理模式Proxy

    一,总体概要 1,笔者浅谈 当我们浏览网页时,网页中的图片有时不会立即展示出来,这就是通过虚拟代理来替代了真实的图片,而代理存储了真实图片的路径和尺寸,这就是代理方式的一种. 代理模式是比较有用途的一 ...

  8. js设计模式(9)---代理模式

    0.前言 KG.PP被交易到了布鲁克林篮网,我的心情很复杂,一方面为他们不能终老celtics感到惋惜,另一方面为他们能够再次冲击总冠军感到高兴.从07年以来,作为一个铁杆celtics球迷,他们给我 ...

  9. JS 设计模式六 -- 代理模式

    概念 为一个对象提供一个代用品或占位符,以便控制对它的访问. 当客户不方便直接访问一个对象的时候,需要提供一个替身对象来控制对这个对象的访问. 替身对象对请求做出一些处理之后, 再把请求转交给本体对象 ...

随机推荐

  1. Android实现splash

    笔者近日遇到一个android中双splash的问题.要求先实现百度的logo,在接入自己的logo. public class MainActivity extends BaseActivity { ...

  2. Ramsey's_theorem Friendship Theorem 友谊定理

    w https://en.wikipedia.org/wiki/Ramsey's_theorem https://zh.wikipedia.org/wiki/拉姆齐定理 在组合数学上,拉姆齐(Rams ...

  3. 避免每次都用sudo使用docker

    默认安装完 docker 后,每次执行 docker 都需要运行 sudo 命令,非常浪费时间影响效率.如果不跟 sudo,直接执行 docker images 命令会有如下问题: FATA[0000 ...

  4. CentOS 7.4 下安装Epel源和Nginx

    EPEL (Extra Packages for Enterprise Linux)是基于Fedora的一个项目,为“红帽系”的操作系统提供额外的软件包,适用于RHEL.CentOS和Scientif ...

  5. VMware虚拟机不能联网的解决办法

    Linux安装的centos系统,不能正常连接网络 1.编辑config文件 [root@localhost ~]# cd /etc/selinux [root@localhost selinux]# ...

  6. P2P-BT对端管理协议(附BT协议1.0)

    对端管理 指的是远端peer集合的管理(尽管自身client也能够视为一个peer.但对端管理不包括自身peer) 一个client(client)必须维持与每一个远程peer连接的状态信息,即1V1 ...

  7. ActiveMQ 核心概念

    1.Failover 当A无法为客户服务时,系统能够自动地切换,使B能够及时地顶上继续为客户提供服务,且客户感觉不到这个为他提供服务的对象已经更换. 如数据库.应用服务.硬件设备等的失效转移. 2.S ...

  8. spring中配置缓存—ehcache

    常用的缓存工具有ehcache.memcache和redis,这里介绍spring中ehcache的配置. 1.在pom添加依赖: <!-- ehcache 相关依赖 --> <de ...

  9. spring项目报org.apache.tiles.definition.DefinitionsFactoryException: I/O错误原因及解决办法。

    今天升级一个spring项目遇到如下错: HTTP Status 500 - Request processing failed; nested exception is org.apache.til ...

  10. id函数

    描述 id() 函数用于获取对象的内存地址. 语法 id 语法: id([object]) 参数说明: object -- 对象. 返回值 返回对象的内存地址. 实例 以下实例展示了 id 的使用方法 ...