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

代理模式类图:

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

抽象主题角色(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. DataTable数据筛选

    DataView view = newDt.DefaultView;view.Sort = "Description asc,replyEnd desc";DataTable ta ...

  2. 亚马逊订单api重构 api异常入库 在php中执行python

    https://docs.python.org/2/library/xml.etree.elementtree.html python  较 php能更高效第处理xml xpth php  扮演什么角 ...

  3. Maven 手动把本地jar安装到本地仓库

    首先,你要安装的.jar包要下载下来放在电脑上面,然后maven已经配置好了,如下图: 然后,执行一下命令就可以了 mvn install:install-file -Dfile=path-to-fi ...

  4. Docker + ElasticSearch + Node.js

    最近有空就想研究下ElasticSearch. 此篇文章用来记录研究过程.备注:需要有一定的docker基础,ElasticSearch的基本概念 Docker安装ElasticSearch 首先,就 ...

  5. Python操作Redis(一)

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

  6. Thrift官方安装手册(译)

    本篇是Thrift官网安装文档的翻译,原地址点击这里.Thrift之前是不支持Windows的.但是似乎0.9版本以后已经支持Window了.介绍了Thrift安装的环境要求以及在centos,Deb ...

  7. windows 安装 python _ flask

    1:首先安装python虚拟环境;(略) 2: 添加一个虚拟环境: 在你的项目目录里直接 virtualenv venv 启动虚拟环境;\venv\Scripts 直接运行activate 3: 在虚 ...

  8. JQuery 评分系统

              评分: ☆ ☆ ☆ ☆ ☆ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...

  9. windows通过ftp下载linux文件

    # windows 下载 linux的文件>> ftp <domain_or_ip>>> <input_username>>> <in ...

  10. HTTP协议—常见的HTTP响应状态码解析

    常见的HTTP响应状态码解析 1XX Informational(信息性状态码) 2XX Success(成功状态码) 3XX Redirection(重定向状态码) 4XX Client Error ...